mirror of
https://github.com/adulau/aha.git
synced 2024-12-26 18:56:14 +00:00
Merge branch 'misc-2.6.33' into release
This commit is contained in:
commit
fcb11235d3
12 changed files with 434 additions and 308 deletions
|
@ -3652,6 +3652,11 @@ W: http://0pointer.de/lennart/tchibo.html
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/platform/x86/msi-laptop.c
|
F: drivers/platform/x86/msi-laptop.c
|
||||||
|
|
||||||
|
MSI WMI SUPPORT
|
||||||
|
M: Anisse Astier <anisse@astier.eu>
|
||||||
|
S: Supported
|
||||||
|
F: drivers/platform/x86/msi-wmi.c
|
||||||
|
|
||||||
MULTIFUNCTION DEVICES (MFD)
|
MULTIFUNCTION DEVICES (MFD)
|
||||||
M: Samuel Ortiz <sameo@linux.intel.com>
|
M: Samuel Ortiz <sameo@linux.intel.com>
|
||||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6.git
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6.git
|
||||||
|
|
|
@ -190,9 +190,11 @@ static void do_drv_write(void *_cmd)
|
||||||
|
|
||||||
static void drv_read(struct drv_cmd *cmd)
|
static void drv_read(struct drv_cmd *cmd)
|
||||||
{
|
{
|
||||||
|
int err;
|
||||||
cmd->val = 0;
|
cmd->val = 0;
|
||||||
|
|
||||||
smp_call_function_single(cpumask_any(cmd->mask), do_drv_read, cmd, 1);
|
err = smp_call_function_any(cmd->mask, do_drv_read, cmd, 1);
|
||||||
|
WARN_ON_ONCE(err); /* smp_call_function_any() was buggy? */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drv_write(struct drv_cmd *cmd)
|
static void drv_write(struct drv_cmd *cmd)
|
||||||
|
|
|
@ -40,7 +40,6 @@ config ATA_VERBOSE_ERROR
|
||||||
config ATA_ACPI
|
config ATA_ACPI
|
||||||
bool "ATA ACPI Support"
|
bool "ATA ACPI Support"
|
||||||
depends on ACPI && PCI
|
depends on ACPI && PCI
|
||||||
select ACPI_DOCK
|
|
||||||
default y
|
default y
|
||||||
help
|
help
|
||||||
This option adds support for ATA-related ACPI objects.
|
This option adds support for ATA-related ACPI objects.
|
||||||
|
|
|
@ -96,9 +96,6 @@ struct acer_quirks {
|
||||||
MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB");
|
MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB");
|
||||||
MODULE_ALIAS("wmi:6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3");
|
MODULE_ALIAS("wmi:6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3");
|
||||||
|
|
||||||
/* Temporary workaround until the WMI sysfs interface goes in */
|
|
||||||
MODULE_ALIAS("dmi:*:*Acer*:*:");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Interface capability flags
|
* Interface capability flags
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
*/
|
*/
|
||||||
#undef START_IN_KERNEL_MODE
|
#undef START_IN_KERNEL_MODE
|
||||||
|
|
||||||
#define DRV_VER "0.5.20"
|
#define DRV_VER "0.5.22"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* According to the Atom N270 datasheet,
|
* According to the Atom N270 datasheet,
|
||||||
|
@ -156,19 +156,25 @@ static const struct bios_settings_t bios_tbl[] = {
|
||||||
{"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x20, 0x00} },
|
{"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x20, 0x00} },
|
||||||
/* Acer 1410 */
|
/* Acer 1410 */
|
||||||
{"Acer", "Aspire 1410", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} },
|
{"Acer", "Aspire 1410", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} },
|
||||||
/* special BIOS / other */
|
{"Acer", "Aspire 1410", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} },
|
||||||
|
/* Acer 1810xx */
|
||||||
|
{"Acer", "Aspire 1810TZ", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} },
|
||||||
|
{"Acer", "Aspire 1810T", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} },
|
||||||
|
{"Acer", "Aspire 1810T", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} },
|
||||||
|
{"Acer", "Aspire 1810TZ", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} },
|
||||||
|
/* Gateway */
|
||||||
{"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x21, 0x00} },
|
{"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x21, 0x00} },
|
||||||
{"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x20, 0x00} },
|
{"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x20, 0x00} },
|
||||||
{"Gateway ", "LT31 ", "v1.3103 ", 0x55, 0x58,
|
{"Gateway", "LT31", "v1.3103", 0x55, 0x58, {0x10, 0x0f, 0x00} },
|
||||||
{0x10, 0x0f, 0x00} },
|
{"Gateway", "LT31", "v1.3201", 0x55, 0x58, {0x10, 0x0f, 0x00} },
|
||||||
{"Gateway ", "LT31 ", "v1.3201 ", 0x55, 0x58,
|
{"Gateway", "LT31", "v1.3302", 0x55, 0x58, {0x10, 0x0f, 0x00} },
|
||||||
{0x10, 0x0f, 0x00} },
|
/* Packard Bell */
|
||||||
{"Gateway ", "LT31 ", "v1.3302 ", 0x55, 0x58,
|
|
||||||
{0x10, 0x0f, 0x00} },
|
|
||||||
{"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x21, 0x00} },
|
{"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x21, 0x00} },
|
||||||
{"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x20, 0x00} },
|
{"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x20, 0x00} },
|
||||||
{"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x21, 0x00} },
|
{"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x21, 0x00} },
|
||||||
{"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x20, 0x00} },
|
{"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x20, 0x00} },
|
||||||
|
{"Packard Bell", "DOTMU", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} },
|
||||||
|
{"Packard Bell", "DOTMU", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} },
|
||||||
/* pewpew-terminator */
|
/* pewpew-terminator */
|
||||||
{"", "", "", 0, 0, {0, 0, 0} }
|
{"", "", "", 0, 0, {0, 0, 0} }
|
||||||
};
|
};
|
||||||
|
@ -486,13 +492,26 @@ static struct platform_driver acerhdf_driver = {
|
||||||
.remove = acerhdf_remove,
|
.remove = acerhdf_remove,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* checks if str begins with start */
|
||||||
|
static int str_starts_with(const char *str, const char *start)
|
||||||
|
{
|
||||||
|
unsigned long str_len = 0, start_len = 0;
|
||||||
|
|
||||||
|
str_len = strlen(str);
|
||||||
|
start_len = strlen(start);
|
||||||
|
|
||||||
|
if (str_len >= start_len &&
|
||||||
|
!strncmp(str, start, start_len))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* check hardware */
|
/* check hardware */
|
||||||
static int acerhdf_check_hardware(void)
|
static int acerhdf_check_hardware(void)
|
||||||
{
|
{
|
||||||
char const *vendor, *version, *product;
|
char const *vendor, *version, *product;
|
||||||
int i;
|
const struct bios_settings_t *bt = NULL;
|
||||||
unsigned long prod_len = 0;
|
|
||||||
|
|
||||||
/* get BIOS data */
|
/* get BIOS data */
|
||||||
vendor = dmi_get_system_info(DMI_SYS_VENDOR);
|
vendor = dmi_get_system_info(DMI_SYS_VENDOR);
|
||||||
|
@ -514,20 +533,20 @@ static int acerhdf_check_hardware(void)
|
||||||
kernelmode = 0;
|
kernelmode = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
prod_len = strlen(product);
|
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
pr_info("BIOS info: %s %s, product: %s\n",
|
pr_info("BIOS info: %s %s, product: %s\n",
|
||||||
vendor, version, product);
|
vendor, version, product);
|
||||||
|
|
||||||
/* search BIOS version and vendor in BIOS settings table */
|
/* search BIOS version and vendor in BIOS settings table */
|
||||||
for (i = 0; bios_tbl[i].version[0]; i++) {
|
for (bt = bios_tbl; bt->vendor[0]; bt++) {
|
||||||
if (strlen(bios_tbl[i].product) >= prod_len &&
|
/*
|
||||||
!strncmp(bios_tbl[i].product, product,
|
* check if actual hardware BIOS vendor, product and version
|
||||||
strlen(bios_tbl[i].product)) &&
|
* IDs start with the strings of BIOS table entry
|
||||||
!strcmp(bios_tbl[i].vendor, vendor) &&
|
*/
|
||||||
!strcmp(bios_tbl[i].version, version)) {
|
if (str_starts_with(vendor, bt->vendor) &&
|
||||||
bios_cfg = &bios_tbl[i];
|
str_starts_with(product, bt->product) &&
|
||||||
|
str_starts_with(version, bt->version)) {
|
||||||
|
bios_cfg = bt;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -640,9 +659,14 @@ static void __exit acerhdf_exit(void)
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_AUTHOR("Peter Feuerer");
|
MODULE_AUTHOR("Peter Feuerer");
|
||||||
MODULE_DESCRIPTION("Aspire One temperature and fan driver");
|
MODULE_DESCRIPTION("Aspire One temperature and fan driver");
|
||||||
MODULE_ALIAS("dmi:*:*Acer*:*:");
|
MODULE_ALIAS("dmi:*:*Acer*:pnAOA*:");
|
||||||
MODULE_ALIAS("dmi:*:*Gateway*:*:");
|
MODULE_ALIAS("dmi:*:*Acer*:pnAspire 1410*:");
|
||||||
MODULE_ALIAS("dmi:*:*Packard Bell*:*:");
|
MODULE_ALIAS("dmi:*:*Acer*:pnAspire 1810*:");
|
||||||
|
MODULE_ALIAS("dmi:*:*Gateway*:pnAOA*:");
|
||||||
|
MODULE_ALIAS("dmi:*:*Gateway*:pnLT31*:");
|
||||||
|
MODULE_ALIAS("dmi:*:*Packard Bell*:pnAOA*:");
|
||||||
|
MODULE_ALIAS("dmi:*:*Packard Bell*:pnDOA*:");
|
||||||
|
MODULE_ALIAS("dmi:*:*Packard Bell*:pnDOTMU*:");
|
||||||
|
|
||||||
module_init(acerhdf_init);
|
module_init(acerhdf_init);
|
||||||
module_exit(acerhdf_exit);
|
module_exit(acerhdf_exit);
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/proc_fs.h>
|
#include <linux/proc_fs.h>
|
||||||
|
#include <linux/seq_file.h>
|
||||||
#include <linux/backlight.h>
|
#include <linux/backlight.h>
|
||||||
#include <acpi/acpi_drivers.h>
|
#include <acpi/acpi_drivers.h>
|
||||||
#include <acpi/acpi_bus.h>
|
#include <acpi/acpi_bus.h>
|
||||||
|
@ -513,26 +514,12 @@ static int read_acpi_int(acpi_handle handle, const char *method, int *val)
|
||||||
return (status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER);
|
return (status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static int asus_info_proc_show(struct seq_file *m, void *v)
|
||||||
* We write our info in page, we begin at offset off and cannot write more
|
|
||||||
* than count bytes. We set eof to 1 if we handle those 2 values. We return the
|
|
||||||
* number of bytes written in page
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
proc_read_info(char *page, char **start, off_t off, int count, int *eof,
|
|
||||||
void *data)
|
|
||||||
{
|
{
|
||||||
int len = 0;
|
|
||||||
int temp;
|
int temp;
|
||||||
char buf[16]; /* enough for all info */
|
|
||||||
/*
|
|
||||||
* We use the easy way, we don't care of off and count,
|
|
||||||
* so we don't set eof to 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
len += sprintf(page, ACPI_HOTK_NAME " " ASUS_ACPI_VERSION "\n");
|
seq_printf(m, ACPI_HOTK_NAME " " ASUS_ACPI_VERSION "\n");
|
||||||
len += sprintf(page + len, "Model reference : %s\n",
|
seq_printf(m, "Model reference : %s\n", hotk->methods->name);
|
||||||
hotk->methods->name);
|
|
||||||
/*
|
/*
|
||||||
* The SFUN method probably allows the original driver to get the list
|
* The SFUN method probably allows the original driver to get the list
|
||||||
* of features supported by a given model. For now, 0x0100 or 0x0800
|
* of features supported by a given model. For now, 0x0100 or 0x0800
|
||||||
|
@ -540,8 +527,7 @@ proc_read_info(char *page, char **start, off_t off, int count, int *eof,
|
||||||
* The significance of others is yet to be found.
|
* The significance of others is yet to be found.
|
||||||
*/
|
*/
|
||||||
if (read_acpi_int(hotk->handle, "SFUN", &temp))
|
if (read_acpi_int(hotk->handle, "SFUN", &temp))
|
||||||
len +=
|
seq_printf(m, "SFUN value : 0x%04x\n", temp);
|
||||||
sprintf(page + len, "SFUN value : 0x%04x\n", temp);
|
|
||||||
/*
|
/*
|
||||||
* Another value for userspace: the ASYM method returns 0x02 for
|
* Another value for userspace: the ASYM method returns 0x02 for
|
||||||
* battery low and 0x04 for battery critical, its readings tend to be
|
* battery low and 0x04 for battery critical, its readings tend to be
|
||||||
|
@ -550,30 +536,34 @@ proc_read_info(char *page, char **start, off_t off, int count, int *eof,
|
||||||
* silently ignored.
|
* silently ignored.
|
||||||
*/
|
*/
|
||||||
if (read_acpi_int(hotk->handle, "ASYM", &temp))
|
if (read_acpi_int(hotk->handle, "ASYM", &temp))
|
||||||
len +=
|
seq_printf(m, "ASYM value : 0x%04x\n", temp);
|
||||||
sprintf(page + len, "ASYM value : 0x%04x\n", temp);
|
|
||||||
if (asus_info) {
|
if (asus_info) {
|
||||||
snprintf(buf, 16, "%d", asus_info->length);
|
seq_printf(m, "DSDT length : %d\n", asus_info->length);
|
||||||
len += sprintf(page + len, "DSDT length : %s\n", buf);
|
seq_printf(m, "DSDT checksum : %d\n", asus_info->checksum);
|
||||||
snprintf(buf, 16, "%d", asus_info->checksum);
|
seq_printf(m, "DSDT revision : %d\n", asus_info->revision);
|
||||||
len += sprintf(page + len, "DSDT checksum : %s\n", buf);
|
seq_printf(m, "OEM id : %.*s\n", ACPI_OEM_ID_SIZE, asus_info->oem_id);
|
||||||
snprintf(buf, 16, "%d", asus_info->revision);
|
seq_printf(m, "OEM table id : %.*s\n", ACPI_OEM_TABLE_ID_SIZE, asus_info->oem_table_id);
|
||||||
len += sprintf(page + len, "DSDT revision : %s\n", buf);
|
seq_printf(m, "OEM revision : 0x%x\n", asus_info->oem_revision);
|
||||||
snprintf(buf, 7, "%s", asus_info->oem_id);
|
seq_printf(m, "ASL comp vendor id : %.*s\n", ACPI_NAME_SIZE, asus_info->asl_compiler_id);
|
||||||
len += sprintf(page + len, "OEM id : %s\n", buf);
|
seq_printf(m, "ASL comp revision : 0x%x\n", asus_info->asl_compiler_revision);
|
||||||
snprintf(buf, 9, "%s", asus_info->oem_table_id);
|
|
||||||
len += sprintf(page + len, "OEM table id : %s\n", buf);
|
|
||||||
snprintf(buf, 16, "%x", asus_info->oem_revision);
|
|
||||||
len += sprintf(page + len, "OEM revision : 0x%s\n", buf);
|
|
||||||
snprintf(buf, 5, "%s", asus_info->asl_compiler_id);
|
|
||||||
len += sprintf(page + len, "ASL comp vendor id : %s\n", buf);
|
|
||||||
snprintf(buf, 16, "%x", asus_info->asl_compiler_revision);
|
|
||||||
len += sprintf(page + len, "ASL comp revision : 0x%s\n", buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return len;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int asus_info_proc_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
return single_open(file, asus_info_proc_show, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct file_operations asus_info_proc_fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.open = asus_info_proc_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* /proc handlers
|
* /proc handlers
|
||||||
* We write our info in page, we begin at offset off and cannot write more
|
* We write our info in page, we begin at offset off and cannot write more
|
||||||
|
@ -639,34 +629,48 @@ write_led(const char __user *buffer, unsigned long count,
|
||||||
/*
|
/*
|
||||||
* Proc handlers for MLED
|
* Proc handlers for MLED
|
||||||
*/
|
*/
|
||||||
static int
|
static int mled_proc_show(struct seq_file *m, void *v)
|
||||||
proc_read_mled(char *page, char **start, off_t off, int count, int *eof,
|
|
||||||
void *data)
|
|
||||||
{
|
{
|
||||||
return sprintf(page, "%d\n",
|
seq_printf(m, "%d\n", read_led(hotk->methods->mled_status, MLED_ON));
|
||||||
read_led(hotk->methods->mled_status, MLED_ON));
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int mled_proc_open(struct inode *inode, struct file *file)
|
||||||
proc_write_mled(struct file *file, const char __user *buffer,
|
{
|
||||||
unsigned long count, void *data)
|
return single_open(file, mled_proc_show, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t mled_proc_write(struct file *file, const char __user *buffer,
|
||||||
|
size_t count, loff_t *pos)
|
||||||
{
|
{
|
||||||
return write_led(buffer, count, hotk->methods->mt_mled, MLED_ON, 1);
|
return write_led(buffer, count, hotk->methods->mt_mled, MLED_ON, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct file_operations mled_proc_fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.open = mled_proc_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
|
.write = mled_proc_write,
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Proc handlers for LED display
|
* Proc handlers for LED display
|
||||||
*/
|
*/
|
||||||
static int
|
static int ledd_proc_show(struct seq_file *m, void *v)
|
||||||
proc_read_ledd(char *page, char **start, off_t off, int count, int *eof,
|
|
||||||
void *data)
|
|
||||||
{
|
{
|
||||||
return sprintf(page, "0x%08x\n", hotk->ledd_status);
|
seq_printf(m, "0x%08x\n", hotk->ledd_status);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int ledd_proc_open(struct inode *inode, struct file *file)
|
||||||
proc_write_ledd(struct file *file, const char __user *buffer,
|
{
|
||||||
unsigned long count, void *data)
|
return single_open(file, ledd_proc_show, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t ledd_proc_write(struct file *file, const char __user *buffer,
|
||||||
|
size_t count, loff_t *pos)
|
||||||
{
|
{
|
||||||
int rv, value;
|
int rv, value;
|
||||||
|
|
||||||
|
@ -682,61 +686,104 @@ proc_write_ledd(struct file *file, const char __user *buffer,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct file_operations ledd_proc_fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.open = ledd_proc_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
|
.write = ledd_proc_write,
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Proc handlers for WLED
|
* Proc handlers for WLED
|
||||||
*/
|
*/
|
||||||
static int
|
static int wled_proc_show(struct seq_file *m, void *v)
|
||||||
proc_read_wled(char *page, char **start, off_t off, int count, int *eof,
|
|
||||||
void *data)
|
|
||||||
{
|
{
|
||||||
return sprintf(page, "%d\n",
|
seq_printf(m, "%d\n", read_led(hotk->methods->wled_status, WLED_ON));
|
||||||
read_led(hotk->methods->wled_status, WLED_ON));
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int wled_proc_open(struct inode *inode, struct file *file)
|
||||||
proc_write_wled(struct file *file, const char __user *buffer,
|
{
|
||||||
unsigned long count, void *data)
|
return single_open(file, wled_proc_show, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t wled_proc_write(struct file *file, const char __user *buffer,
|
||||||
|
size_t count, loff_t *pos)
|
||||||
{
|
{
|
||||||
return write_led(buffer, count, hotk->methods->mt_wled, WLED_ON, 0);
|
return write_led(buffer, count, hotk->methods->mt_wled, WLED_ON, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct file_operations wled_proc_fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.open = wled_proc_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
|
.write = wled_proc_write,
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Proc handlers for Bluetooth
|
* Proc handlers for Bluetooth
|
||||||
*/
|
*/
|
||||||
static int
|
static int bluetooth_proc_show(struct seq_file *m, void *v)
|
||||||
proc_read_bluetooth(char *page, char **start, off_t off, int count, int *eof,
|
|
||||||
void *data)
|
|
||||||
{
|
{
|
||||||
return sprintf(page, "%d\n", read_led(hotk->methods->bt_status, BT_ON));
|
seq_printf(m, "%d\n", read_led(hotk->methods->bt_status, BT_ON));
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int bluetooth_proc_open(struct inode *inode, struct file *file)
|
||||||
proc_write_bluetooth(struct file *file, const char __user *buffer,
|
{
|
||||||
unsigned long count, void *data)
|
return single_open(file, bluetooth_proc_show, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t bluetooth_proc_write(struct file *file,
|
||||||
|
const char __user *buffer, size_t count, loff_t *pos)
|
||||||
{
|
{
|
||||||
/* Note: mt_bt_switch controls both internal Bluetooth adapter's
|
/* Note: mt_bt_switch controls both internal Bluetooth adapter's
|
||||||
presence and its LED */
|
presence and its LED */
|
||||||
return write_led(buffer, count, hotk->methods->mt_bt_switch, BT_ON, 0);
|
return write_led(buffer, count, hotk->methods->mt_bt_switch, BT_ON, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct file_operations bluetooth_proc_fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.open = bluetooth_proc_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
|
.write = bluetooth_proc_write,
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Proc handlers for TLED
|
* Proc handlers for TLED
|
||||||
*/
|
*/
|
||||||
static int
|
static int tled_proc_show(struct seq_file *m, void *v)
|
||||||
proc_read_tled(char *page, char **start, off_t off, int count, int *eof,
|
|
||||||
void *data)
|
|
||||||
{
|
{
|
||||||
return sprintf(page, "%d\n",
|
seq_printf(m, "%d\n", read_led(hotk->methods->tled_status, TLED_ON));
|
||||||
read_led(hotk->methods->tled_status, TLED_ON));
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int tled_proc_open(struct inode *inode, struct file *file)
|
||||||
proc_write_tled(struct file *file, const char __user *buffer,
|
{
|
||||||
unsigned long count, void *data)
|
return single_open(file, tled_proc_show, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t tled_proc_write(struct file *file, const char __user *buffer,
|
||||||
|
size_t count, loff_t *pos)
|
||||||
{
|
{
|
||||||
return write_led(buffer, count, hotk->methods->mt_tled, TLED_ON, 0);
|
return write_led(buffer, count, hotk->methods->mt_tled, TLED_ON, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct file_operations tled_proc_fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.open = tled_proc_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
|
.write = tled_proc_write,
|
||||||
|
};
|
||||||
|
|
||||||
static int get_lcd_state(void)
|
static int get_lcd_state(void)
|
||||||
{
|
{
|
||||||
int lcd = 0;
|
int lcd = 0;
|
||||||
|
@ -829,16 +876,19 @@ static int set_lcd_state(int value)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int lcd_proc_show(struct seq_file *m, void *v)
|
||||||
proc_read_lcd(char *page, char **start, off_t off, int count, int *eof,
|
|
||||||
void *data)
|
|
||||||
{
|
{
|
||||||
return sprintf(page, "%d\n", get_lcd_state());
|
seq_printf(m, "%d\n", get_lcd_state());
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int lcd_proc_open(struct inode *inode, struct file *file)
|
||||||
proc_write_lcd(struct file *file, const char __user *buffer,
|
{
|
||||||
unsigned long count, void *data)
|
return single_open(file, lcd_proc_show, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t lcd_proc_write(struct file *file, const char __user *buffer,
|
||||||
|
size_t count, loff_t *pos)
|
||||||
{
|
{
|
||||||
int rv, value;
|
int rv, value;
|
||||||
|
|
||||||
|
@ -848,6 +898,15 @@ proc_write_lcd(struct file *file, const char __user *buffer,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct file_operations lcd_proc_fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.open = lcd_proc_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
|
.write = lcd_proc_write,
|
||||||
|
};
|
||||||
|
|
||||||
static int read_brightness(struct backlight_device *bd)
|
static int read_brightness(struct backlight_device *bd)
|
||||||
{
|
{
|
||||||
int value;
|
int value;
|
||||||
|
@ -907,16 +966,19 @@ static int set_brightness_status(struct backlight_device *bd)
|
||||||
return set_brightness(bd->props.brightness);
|
return set_brightness(bd->props.brightness);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int brn_proc_show(struct seq_file *m, void *v)
|
||||||
proc_read_brn(char *page, char **start, off_t off, int count, int *eof,
|
|
||||||
void *data)
|
|
||||||
{
|
{
|
||||||
return sprintf(page, "%d\n", read_brightness(NULL));
|
seq_printf(m, "%d\n", read_brightness(NULL));
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int brn_proc_open(struct inode *inode, struct file *file)
|
||||||
proc_write_brn(struct file *file, const char __user *buffer,
|
{
|
||||||
unsigned long count, void *data)
|
return single_open(file, brn_proc_show, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t brn_proc_write(struct file *file, const char __user *buffer,
|
||||||
|
size_t count, loff_t *pos)
|
||||||
{
|
{
|
||||||
int rv, value;
|
int rv, value;
|
||||||
|
|
||||||
|
@ -929,6 +991,15 @@ proc_write_brn(struct file *file, const char __user *buffer,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct file_operations brn_proc_fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.open = brn_proc_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
|
.write = brn_proc_write,
|
||||||
|
};
|
||||||
|
|
||||||
static void set_display(int value)
|
static void set_display(int value)
|
||||||
{
|
{
|
||||||
/* no sanity check needed for now */
|
/* no sanity check needed for now */
|
||||||
|
@ -942,9 +1013,7 @@ static void set_display(int value)
|
||||||
* Now, *this* one could be more user-friendly, but so far, no-one has
|
* Now, *this* one could be more user-friendly, but so far, no-one has
|
||||||
* complained. The significance of bits is the same as in proc_write_disp()
|
* complained. The significance of bits is the same as in proc_write_disp()
|
||||||
*/
|
*/
|
||||||
static int
|
static int disp_proc_show(struct seq_file *m, void *v)
|
||||||
proc_read_disp(char *page, char **start, off_t off, int count, int *eof,
|
|
||||||
void *data)
|
|
||||||
{
|
{
|
||||||
int value = 0;
|
int value = 0;
|
||||||
|
|
||||||
|
@ -952,7 +1021,13 @@ proc_read_disp(char *page, char **start, off_t off, int count, int *eof,
|
||||||
printk(KERN_WARNING
|
printk(KERN_WARNING
|
||||||
"Asus ACPI: Error reading display status\n");
|
"Asus ACPI: Error reading display status\n");
|
||||||
value &= 0x07; /* needed for some models, shouldn't hurt others */
|
value &= 0x07; /* needed for some models, shouldn't hurt others */
|
||||||
return sprintf(page, "%d\n", value);
|
seq_printf(m, "%d\n", value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int disp_proc_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
return single_open(file, disp_proc_show, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -961,9 +1036,8 @@ proc_read_disp(char *page, char **start, off_t off, int count, int *eof,
|
||||||
* (bitwise) of these will suffice. I never actually tested 3 displays hooked
|
* (bitwise) of these will suffice. I never actually tested 3 displays hooked
|
||||||
* up simultaneously, so be warned. See the acpi4asus README for more info.
|
* up simultaneously, so be warned. See the acpi4asus README for more info.
|
||||||
*/
|
*/
|
||||||
static int
|
static ssize_t disp_proc_write(struct file *file, const char __user *buffer,
|
||||||
proc_write_disp(struct file *file, const char __user *buffer,
|
size_t count, loff_t *pos)
|
||||||
unsigned long count, void *data)
|
|
||||||
{
|
{
|
||||||
int rv, value;
|
int rv, value;
|
||||||
|
|
||||||
|
@ -973,25 +1047,27 @@ proc_write_disp(struct file *file, const char __user *buffer,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef int (proc_readfunc) (char *page, char **start, off_t off, int count,
|
static const struct file_operations disp_proc_fops = {
|
||||||
int *eof, void *data);
|
.owner = THIS_MODULE,
|
||||||
typedef int (proc_writefunc) (struct file *file, const char __user *buffer,
|
.open = disp_proc_open,
|
||||||
unsigned long count, void *data);
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
|
.write = disp_proc_write,
|
||||||
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
asus_proc_add(char *name, proc_writefunc *writefunc,
|
asus_proc_add(char *name, const struct file_operations *proc_fops, mode_t mode,
|
||||||
proc_readfunc *readfunc, mode_t mode,
|
|
||||||
struct acpi_device *device)
|
struct acpi_device *device)
|
||||||
{
|
{
|
||||||
struct proc_dir_entry *proc =
|
struct proc_dir_entry *proc;
|
||||||
create_proc_entry(name, mode, acpi_device_dir(device));
|
|
||||||
|
proc = proc_create_data(name, mode, acpi_device_dir(device),
|
||||||
|
proc_fops, acpi_driver_data(device));
|
||||||
if (!proc) {
|
if (!proc) {
|
||||||
printk(KERN_WARNING " Unable to create %s fs entry\n", name);
|
printk(KERN_WARNING " Unable to create %s fs entry\n", name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
proc->write_proc = writefunc;
|
|
||||||
proc->read_proc = readfunc;
|
|
||||||
proc->data = acpi_driver_data(device);
|
|
||||||
proc->uid = asus_uid;
|
proc->uid = asus_uid;
|
||||||
proc->gid = asus_gid;
|
proc->gid = asus_gid;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1020,10 +1096,9 @@ static int asus_hotk_add_fs(struct acpi_device *device)
|
||||||
if (!acpi_device_dir(device))
|
if (!acpi_device_dir(device))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
proc = create_proc_entry(PROC_INFO, mode, acpi_device_dir(device));
|
proc = proc_create(PROC_INFO, mode, acpi_device_dir(device),
|
||||||
|
&asus_info_proc_fops);
|
||||||
if (proc) {
|
if (proc) {
|
||||||
proc->read_proc = proc_read_info;
|
|
||||||
proc->data = acpi_driver_data(device);
|
|
||||||
proc->uid = asus_uid;
|
proc->uid = asus_uid;
|
||||||
proc->gid = asus_gid;
|
proc->gid = asus_gid;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1032,28 +1107,23 @@ static int asus_hotk_add_fs(struct acpi_device *device)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hotk->methods->mt_wled) {
|
if (hotk->methods->mt_wled) {
|
||||||
asus_proc_add(PROC_WLED, &proc_write_wled, &proc_read_wled,
|
asus_proc_add(PROC_WLED, &wled_proc_fops, mode, device);
|
||||||
mode, device);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hotk->methods->mt_ledd) {
|
if (hotk->methods->mt_ledd) {
|
||||||
asus_proc_add(PROC_LEDD, &proc_write_ledd, &proc_read_ledd,
|
asus_proc_add(PROC_LEDD, &ledd_proc_fops, mode, device);
|
||||||
mode, device);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hotk->methods->mt_mled) {
|
if (hotk->methods->mt_mled) {
|
||||||
asus_proc_add(PROC_MLED, &proc_write_mled, &proc_read_mled,
|
asus_proc_add(PROC_MLED, &mled_proc_fops, mode, device);
|
||||||
mode, device);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hotk->methods->mt_tled) {
|
if (hotk->methods->mt_tled) {
|
||||||
asus_proc_add(PROC_TLED, &proc_write_tled, &proc_read_tled,
|
asus_proc_add(PROC_TLED, &tled_proc_fops, mode, device);
|
||||||
mode, device);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hotk->methods->mt_bt_switch) {
|
if (hotk->methods->mt_bt_switch) {
|
||||||
asus_proc_add(PROC_BT, &proc_write_bluetooth,
|
asus_proc_add(PROC_BT, &bluetooth_proc_fops, mode, device);
|
||||||
&proc_read_bluetooth, mode, device);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1061,19 +1131,16 @@ static int asus_hotk_add_fs(struct acpi_device *device)
|
||||||
* accessible from the keyboard
|
* accessible from the keyboard
|
||||||
*/
|
*/
|
||||||
if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status) {
|
if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status) {
|
||||||
asus_proc_add(PROC_LCD, &proc_write_lcd, &proc_read_lcd, mode,
|
asus_proc_add(PROC_LCD, &lcd_proc_fops, mode, device);
|
||||||
device);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((hotk->methods->brightness_up && hotk->methods->brightness_down) ||
|
if ((hotk->methods->brightness_up && hotk->methods->brightness_down) ||
|
||||||
(hotk->methods->brightness_get && hotk->methods->brightness_set)) {
|
(hotk->methods->brightness_get && hotk->methods->brightness_set)) {
|
||||||
asus_proc_add(PROC_BRN, &proc_write_brn, &proc_read_brn, mode,
|
asus_proc_add(PROC_BRN, &brn_proc_fops, mode, device);
|
||||||
device);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hotk->methods->display_set) {
|
if (hotk->methods->display_set) {
|
||||||
asus_proc_add(PROC_DISP, &proc_write_disp, &proc_read_disp,
|
asus_proc_add(PROC_DISP, &disp_proc_fops, mode, device);
|
||||||
mode, device);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -238,6 +238,7 @@ static void dell_wmi_notify(u32 value, void *context)
|
||||||
input_sync(dell_wmi_input_dev);
|
input_sync(dell_wmi_input_dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
kfree(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -324,11 +325,14 @@ static int __init dell_wmi_init(void)
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (wmi_has_guid(DELL_EVENT_GUID)) {
|
if (wmi_has_guid(DELL_EVENT_GUID)) {
|
||||||
|
printk(KERN_WARNING "dell-wmi: No known WMI GUID found\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
dmi_walk(find_hk_type, NULL);
|
dmi_walk(find_hk_type, NULL);
|
||||||
|
acpi_video = acpi_video_backlight_support();
|
||||||
|
|
||||||
err = dell_wmi_input_setup();
|
err = dell_wmi_input_setup();
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -336,25 +340,19 @@ static int __init dell_wmi_init(void)
|
||||||
dell_wmi_notify, NULL);
|
dell_wmi_notify, NULL);
|
||||||
if (err) {
|
if (err) {
|
||||||
input_unregister_device(dell_wmi_input_dev);
|
input_unregister_device(dell_wmi_input_dev);
|
||||||
printk(KERN_ERR "dell-wmi: Unable to register"
|
printk(KERN_ERR
|
||||||
" notify handler - %d\n", err);
|
"dell-wmi: Unable to register notify handler - %d\n",
|
||||||
|
err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
acpi_video = acpi_video_backlight_support();
|
|
||||||
|
|
||||||
} else
|
|
||||||
printk(KERN_WARNING "dell-wmi: No known WMI GUID found\n");
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit dell_wmi_exit(void)
|
static void __exit dell_wmi_exit(void)
|
||||||
{
|
{
|
||||||
if (wmi_has_guid(DELL_EVENT_GUID)) {
|
|
||||||
wmi_remove_notify_handler(DELL_EVENT_GUID);
|
wmi_remove_notify_handler(DELL_EVENT_GUID);
|
||||||
input_unregister_device(dell_wmi_input_dev);
|
input_unregister_device(dell_wmi_input_dev);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(dell_wmi_init);
|
module_init(dell_wmi_init);
|
||||||
|
|
|
@ -376,8 +376,8 @@ static int get_lcd_level(void)
|
||||||
|
|
||||||
status =
|
status =
|
||||||
acpi_evaluate_integer(fujitsu->acpi_handle, "GBLL", NULL, &state);
|
acpi_evaluate_integer(fujitsu->acpi_handle, "GBLL", NULL, &state);
|
||||||
if (status < 0)
|
if (ACPI_FAILURE(status))
|
||||||
return status;
|
return 0;
|
||||||
|
|
||||||
fujitsu->brightness_level = state & 0x0fffffff;
|
fujitsu->brightness_level = state & 0x0fffffff;
|
||||||
|
|
||||||
|
@ -398,8 +398,8 @@ static int get_max_brightness(void)
|
||||||
|
|
||||||
status =
|
status =
|
||||||
acpi_evaluate_integer(fujitsu->acpi_handle, "RBLL", NULL, &state);
|
acpi_evaluate_integer(fujitsu->acpi_handle, "RBLL", NULL, &state);
|
||||||
if (status < 0)
|
if (ACPI_FAILURE(status))
|
||||||
return status;
|
return -1;
|
||||||
|
|
||||||
fujitsu->max_brightness = state;
|
fujitsu->max_brightness = state;
|
||||||
|
|
||||||
|
|
|
@ -134,10 +134,15 @@ static int hp_wmi_perform_query(int query, int write, int value)
|
||||||
|
|
||||||
obj = output.pointer;
|
obj = output.pointer;
|
||||||
|
|
||||||
if (!obj || obj->type != ACPI_TYPE_BUFFER)
|
if (!obj)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
else if (obj->type != ACPI_TYPE_BUFFER) {
|
||||||
|
kfree(obj);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
bios_return = *((struct bios_return *)obj->buffer.pointer);
|
bios_return = *((struct bios_return *)obj->buffer.pointer);
|
||||||
|
kfree(obj);
|
||||||
if (bios_return.return_code > 0)
|
if (bios_return.return_code > 0)
|
||||||
return bios_return.return_code * -1;
|
return bios_return.return_code * -1;
|
||||||
else
|
else
|
||||||
|
@ -340,10 +345,12 @@ static void hp_wmi_notify(u32 value, void *context)
|
||||||
|
|
||||||
if (!obj || obj->type != ACPI_TYPE_BUFFER || obj->buffer.length != 8) {
|
if (!obj || obj->type != ACPI_TYPE_BUFFER || obj->buffer.length != 8) {
|
||||||
printk(KERN_INFO "HP WMI: Unknown response received\n");
|
printk(KERN_INFO "HP WMI: Unknown response received\n");
|
||||||
|
kfree(obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
eventcode = *((u8 *) obj->buffer.pointer);
|
eventcode = *((u8 *) obj->buffer.pointer);
|
||||||
|
kfree(obj);
|
||||||
if (eventcode == 0x4)
|
if (eventcode == 0x4)
|
||||||
eventcode = hp_wmi_perform_query(HPWMI_HOTKEY_QUERY, 0,
|
eventcode = hp_wmi_perform_query(HPWMI_HOTKEY_QUERY, 0,
|
||||||
0);
|
0);
|
||||||
|
@ -381,6 +388,8 @@ static void hp_wmi_notify(u32 value, void *context)
|
||||||
} else
|
} else
|
||||||
printk(KERN_INFO "HP WMI: Unknown key pressed - %x\n",
|
printk(KERN_INFO "HP WMI: Unknown key pressed - %x\n",
|
||||||
eventcode);
|
eventcode);
|
||||||
|
|
||||||
|
kfree(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init hp_wmi_input_setup(void)
|
static int __init hp_wmi_input_setup(void)
|
||||||
|
|
|
@ -34,16 +34,6 @@ MODULE_LICENSE("GPL");
|
||||||
MODULE_ALIAS("wmi:551A1F84-FBDD-4125-91DB-3EA8F44F1D45");
|
MODULE_ALIAS("wmi:551A1F84-FBDD-4125-91DB-3EA8F44F1D45");
|
||||||
MODULE_ALIAS("wmi:B6F3EEF2-3D2F-49DC-9DE3-85BCE18C62F2");
|
MODULE_ALIAS("wmi:B6F3EEF2-3D2F-49DC-9DE3-85BCE18C62F2");
|
||||||
|
|
||||||
/* Temporary workaround until the WMI sysfs interface goes in
|
|
||||||
{ "svn", DMI_SYS_VENDOR },
|
|
||||||
{ "pn", DMI_PRODUCT_NAME },
|
|
||||||
{ "pvr", DMI_PRODUCT_VERSION },
|
|
||||||
{ "rvn", DMI_BOARD_VENDOR },
|
|
||||||
{ "rn", DMI_BOARD_NAME },
|
|
||||||
*/
|
|
||||||
|
|
||||||
MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnMS-6638:*");
|
|
||||||
|
|
||||||
#define DRV_NAME "msi-wmi"
|
#define DRV_NAME "msi-wmi"
|
||||||
#define DRV_PFX DRV_NAME ": "
|
#define DRV_PFX DRV_NAME ": "
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/proc_fs.h>
|
#include <linux/proc_fs.h>
|
||||||
|
#include <linux/seq_file.h>
|
||||||
#include <linux/backlight.h>
|
#include <linux/backlight.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/rfkill.h>
|
#include <linux/rfkill.h>
|
||||||
|
@ -357,63 +358,6 @@ static int force_fan;
|
||||||
static int last_key_event;
|
static int last_key_event;
|
||||||
static int key_event_valid;
|
static int key_event_valid;
|
||||||
|
|
||||||
typedef struct _ProcItem {
|
|
||||||
const char *name;
|
|
||||||
char *(*read_func) (char *);
|
|
||||||
unsigned long (*write_func) (const char *, unsigned long);
|
|
||||||
} ProcItem;
|
|
||||||
|
|
||||||
/* proc file handlers
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int
|
|
||||||
dispatch_read(char *page, char **start, off_t off, int count, int *eof,
|
|
||||||
ProcItem * item)
|
|
||||||
{
|
|
||||||
char *p = page;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
if (off == 0)
|
|
||||||
p = item->read_func(p);
|
|
||||||
|
|
||||||
/* ISSUE: I don't understand this code */
|
|
||||||
len = (p - page);
|
|
||||||
if (len <= off + count)
|
|
||||||
*eof = 1;
|
|
||||||
*start = page + off;
|
|
||||||
len -= off;
|
|
||||||
if (len > count)
|
|
||||||
len = count;
|
|
||||||
if (len < 0)
|
|
||||||
len = 0;
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
dispatch_write(struct file *file, const char __user * buffer,
|
|
||||||
unsigned long count, ProcItem * item)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
char *tmp_buffer;
|
|
||||||
|
|
||||||
/* Arg buffer points to userspace memory, which can't be accessed
|
|
||||||
* directly. Since we're making a copy, zero-terminate the
|
|
||||||
* destination so that sscanf can be used on it safely.
|
|
||||||
*/
|
|
||||||
tmp_buffer = kmalloc(count + 1, GFP_KERNEL);
|
|
||||||
if (!tmp_buffer)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
if (copy_from_user(tmp_buffer, buffer, count)) {
|
|
||||||
result = -EFAULT;
|
|
||||||
} else {
|
|
||||||
tmp_buffer[count] = 0;
|
|
||||||
result = item->write_func(tmp_buffer, count);
|
|
||||||
}
|
|
||||||
kfree(tmp_buffer);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_lcd(struct backlight_device *bd)
|
static int get_lcd(struct backlight_device *bd)
|
||||||
{
|
{
|
||||||
u32 hci_result;
|
u32 hci_result;
|
||||||
|
@ -426,19 +370,24 @@ static int get_lcd(struct backlight_device *bd)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *read_lcd(char *p)
|
static int lcd_proc_show(struct seq_file *m, void *v)
|
||||||
{
|
{
|
||||||
int value = get_lcd(NULL);
|
int value = get_lcd(NULL);
|
||||||
|
|
||||||
if (value >= 0) {
|
if (value >= 0) {
|
||||||
p += sprintf(p, "brightness: %d\n", value);
|
seq_printf(m, "brightness: %d\n", value);
|
||||||
p += sprintf(p, "brightness_levels: %d\n",
|
seq_printf(m, "brightness_levels: %d\n",
|
||||||
HCI_LCD_BRIGHTNESS_LEVELS);
|
HCI_LCD_BRIGHTNESS_LEVELS);
|
||||||
} else {
|
} else {
|
||||||
printk(MY_ERR "Error reading LCD brightness\n");
|
printk(MY_ERR "Error reading LCD brightness\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return p;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcd_proc_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
return single_open(file, lcd_proc_show, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_lcd(int value)
|
static int set_lcd(int value)
|
||||||
|
@ -458,12 +407,20 @@ static int set_lcd_status(struct backlight_device *bd)
|
||||||
return set_lcd(bd->props.brightness);
|
return set_lcd(bd->props.brightness);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long write_lcd(const char *buffer, unsigned long count)
|
static ssize_t lcd_proc_write(struct file *file, const char __user *buf,
|
||||||
|
size_t count, loff_t *pos)
|
||||||
{
|
{
|
||||||
|
char cmd[42];
|
||||||
|
size_t len;
|
||||||
int value;
|
int value;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (sscanf(buffer, " brightness : %i", &value) == 1 &&
|
len = min(count, sizeof(cmd) - 1);
|
||||||
|
if (copy_from_user(cmd, buf, len))
|
||||||
|
return -EFAULT;
|
||||||
|
cmd[len] = '\0';
|
||||||
|
|
||||||
|
if (sscanf(cmd, " brightness : %i", &value) == 1 &&
|
||||||
value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) {
|
value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) {
|
||||||
ret = set_lcd(value);
|
ret = set_lcd(value);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
|
@ -474,7 +431,16 @@ static unsigned long write_lcd(const char *buffer, unsigned long count)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *read_video(char *p)
|
static const struct file_operations lcd_proc_fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.open = lcd_proc_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
|
.write = lcd_proc_write,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int video_proc_show(struct seq_file *m, void *v)
|
||||||
{
|
{
|
||||||
u32 hci_result;
|
u32 hci_result;
|
||||||
u32 value;
|
u32 value;
|
||||||
|
@ -484,18 +450,25 @@ static char *read_video(char *p)
|
||||||
int is_lcd = (value & HCI_VIDEO_OUT_LCD) ? 1 : 0;
|
int is_lcd = (value & HCI_VIDEO_OUT_LCD) ? 1 : 0;
|
||||||
int is_crt = (value & HCI_VIDEO_OUT_CRT) ? 1 : 0;
|
int is_crt = (value & HCI_VIDEO_OUT_CRT) ? 1 : 0;
|
||||||
int is_tv = (value & HCI_VIDEO_OUT_TV) ? 1 : 0;
|
int is_tv = (value & HCI_VIDEO_OUT_TV) ? 1 : 0;
|
||||||
p += sprintf(p, "lcd_out: %d\n", is_lcd);
|
seq_printf(m, "lcd_out: %d\n", is_lcd);
|
||||||
p += sprintf(p, "crt_out: %d\n", is_crt);
|
seq_printf(m, "crt_out: %d\n", is_crt);
|
||||||
p += sprintf(p, "tv_out: %d\n", is_tv);
|
seq_printf(m, "tv_out: %d\n", is_tv);
|
||||||
} else {
|
} else {
|
||||||
printk(MY_ERR "Error reading video out status\n");
|
printk(MY_ERR "Error reading video out status\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return p;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long write_video(const char *buffer, unsigned long count)
|
static int video_proc_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
|
return single_open(file, video_proc_show, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t video_proc_write(struct file *file, const char __user *buf,
|
||||||
|
size_t count, loff_t *pos)
|
||||||
|
{
|
||||||
|
char *cmd, *buffer;
|
||||||
int value;
|
int value;
|
||||||
int remain = count;
|
int remain = count;
|
||||||
int lcd_out = -1;
|
int lcd_out = -1;
|
||||||
|
@ -504,6 +477,17 @@ static unsigned long write_video(const char *buffer, unsigned long count)
|
||||||
u32 hci_result;
|
u32 hci_result;
|
||||||
u32 video_out;
|
u32 video_out;
|
||||||
|
|
||||||
|
cmd = kmalloc(count + 1, GFP_KERNEL);
|
||||||
|
if (!cmd)
|
||||||
|
return -ENOMEM;
|
||||||
|
if (copy_from_user(cmd, buf, count)) {
|
||||||
|
kfree(cmd);
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
cmd[count] = '\0';
|
||||||
|
|
||||||
|
buffer = cmd;
|
||||||
|
|
||||||
/* scan expression. Multiple expressions may be delimited with ;
|
/* scan expression. Multiple expressions may be delimited with ;
|
||||||
*
|
*
|
||||||
* NOTE: to keep scanning simple, invalid fields are ignored
|
* NOTE: to keep scanning simple, invalid fields are ignored
|
||||||
|
@ -523,6 +507,8 @@ static unsigned long write_video(const char *buffer, unsigned long count)
|
||||||
while (remain && *(buffer - 1) != ';');
|
while (remain && *(buffer - 1) != ';');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kfree(cmd);
|
||||||
|
|
||||||
hci_read1(HCI_VIDEO_OUT, &video_out, &hci_result);
|
hci_read1(HCI_VIDEO_OUT, &video_out, &hci_result);
|
||||||
if (hci_result == HCI_SUCCESS) {
|
if (hci_result == HCI_SUCCESS) {
|
||||||
unsigned int new_video_out = video_out;
|
unsigned int new_video_out = video_out;
|
||||||
|
@ -543,28 +529,50 @@ static unsigned long write_video(const char *buffer, unsigned long count)
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *read_fan(char *p)
|
static const struct file_operations video_proc_fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.open = video_proc_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
|
.write = video_proc_write,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int fan_proc_show(struct seq_file *m, void *v)
|
||||||
{
|
{
|
||||||
u32 hci_result;
|
u32 hci_result;
|
||||||
u32 value;
|
u32 value;
|
||||||
|
|
||||||
hci_read1(HCI_FAN, &value, &hci_result);
|
hci_read1(HCI_FAN, &value, &hci_result);
|
||||||
if (hci_result == HCI_SUCCESS) {
|
if (hci_result == HCI_SUCCESS) {
|
||||||
p += sprintf(p, "running: %d\n", (value > 0));
|
seq_printf(m, "running: %d\n", (value > 0));
|
||||||
p += sprintf(p, "force_on: %d\n", force_fan);
|
seq_printf(m, "force_on: %d\n", force_fan);
|
||||||
} else {
|
} else {
|
||||||
printk(MY_ERR "Error reading fan status\n");
|
printk(MY_ERR "Error reading fan status\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return p;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long write_fan(const char *buffer, unsigned long count)
|
static int fan_proc_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
|
return single_open(file, fan_proc_show, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t fan_proc_write(struct file *file, const char __user *buf,
|
||||||
|
size_t count, loff_t *pos)
|
||||||
|
{
|
||||||
|
char cmd[42];
|
||||||
|
size_t len;
|
||||||
int value;
|
int value;
|
||||||
u32 hci_result;
|
u32 hci_result;
|
||||||
|
|
||||||
if (sscanf(buffer, " force_on : %i", &value) == 1 &&
|
len = min(count, sizeof(cmd) - 1);
|
||||||
|
if (copy_from_user(cmd, buf, len))
|
||||||
|
return -EFAULT;
|
||||||
|
cmd[len] = '\0';
|
||||||
|
|
||||||
|
if (sscanf(cmd, " force_on : %i", &value) == 1 &&
|
||||||
value >= 0 && value <= 1) {
|
value >= 0 && value <= 1) {
|
||||||
hci_write1(HCI_FAN, value, &hci_result);
|
hci_write1(HCI_FAN, value, &hci_result);
|
||||||
if (hci_result != HCI_SUCCESS)
|
if (hci_result != HCI_SUCCESS)
|
||||||
|
@ -578,7 +586,16 @@ static unsigned long write_fan(const char *buffer, unsigned long count)
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *read_keys(char *p)
|
static const struct file_operations fan_proc_fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.open = fan_proc_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
|
.write = fan_proc_write,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int keys_proc_show(struct seq_file *m, void *v)
|
||||||
{
|
{
|
||||||
u32 hci_result;
|
u32 hci_result;
|
||||||
u32 value;
|
u32 value;
|
||||||
|
@ -602,18 +619,30 @@ static char *read_keys(char *p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p += sprintf(p, "hotkey_ready: %d\n", key_event_valid);
|
seq_printf(m, "hotkey_ready: %d\n", key_event_valid);
|
||||||
p += sprintf(p, "hotkey: 0x%04x\n", last_key_event);
|
seq_printf(m, "hotkey: 0x%04x\n", last_key_event);
|
||||||
|
end:
|
||||||
end:
|
return 0;
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long write_keys(const char *buffer, unsigned long count)
|
static int keys_proc_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
|
return single_open(file, keys_proc_show, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t keys_proc_write(struct file *file, const char __user *buf,
|
||||||
|
size_t count, loff_t *pos)
|
||||||
|
{
|
||||||
|
char cmd[42];
|
||||||
|
size_t len;
|
||||||
int value;
|
int value;
|
||||||
|
|
||||||
if (sscanf(buffer, " hotkey_ready : %i", &value) == 1 && value == 0) {
|
len = min(count, sizeof(cmd) - 1);
|
||||||
|
if (copy_from_user(cmd, buf, len))
|
||||||
|
return -EFAULT;
|
||||||
|
cmd[len] = '\0';
|
||||||
|
|
||||||
|
if (sscanf(cmd, " hotkey_ready : %i", &value) == 1 && value == 0) {
|
||||||
key_event_valid = 0;
|
key_event_valid = 0;
|
||||||
} else {
|
} else {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -622,52 +651,58 @@ static unsigned long write_keys(const char *buffer, unsigned long count)
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *read_version(char *p)
|
static const struct file_operations keys_proc_fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.open = keys_proc_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
|
.write = keys_proc_write,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int version_proc_show(struct seq_file *m, void *v)
|
||||||
{
|
{
|
||||||
p += sprintf(p, "driver: %s\n", TOSHIBA_ACPI_VERSION);
|
seq_printf(m, "driver: %s\n", TOSHIBA_ACPI_VERSION);
|
||||||
p += sprintf(p, "proc_interface: %d\n",
|
seq_printf(m, "proc_interface: %d\n", PROC_INTERFACE_VERSION);
|
||||||
PROC_INTERFACE_VERSION);
|
return 0;
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int version_proc_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
return single_open(file, version_proc_show, PDE(inode)->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct file_operations version_proc_fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.open = version_proc_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
|
};
|
||||||
|
|
||||||
/* proc and module init
|
/* proc and module init
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PROC_TOSHIBA "toshiba"
|
#define PROC_TOSHIBA "toshiba"
|
||||||
|
|
||||||
static ProcItem proc_items[] = {
|
|
||||||
{"lcd", read_lcd, write_lcd},
|
|
||||||
{"video", read_video, write_video},
|
|
||||||
{"fan", read_fan, write_fan},
|
|
||||||
{"keys", read_keys, write_keys},
|
|
||||||
{"version", read_version, NULL},
|
|
||||||
{NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
static acpi_status __init add_device(void)
|
static acpi_status __init add_device(void)
|
||||||
{
|
{
|
||||||
struct proc_dir_entry *proc;
|
proc_create("lcd", S_IRUGO | S_IWUSR, toshiba_proc_dir, &lcd_proc_fops);
|
||||||
ProcItem *item;
|
proc_create("video", S_IRUGO | S_IWUSR, toshiba_proc_dir, &video_proc_fops);
|
||||||
|
proc_create("fan", S_IRUGO | S_IWUSR, toshiba_proc_dir, &fan_proc_fops);
|
||||||
for (item = proc_items; item->name; ++item) {
|
proc_create("keys", S_IRUGO | S_IWUSR, toshiba_proc_dir, &keys_proc_fops);
|
||||||
proc = create_proc_read_entry(item->name,
|
proc_create("version", S_IRUGO, toshiba_proc_dir, &version_proc_fops);
|
||||||
S_IFREG | S_IRUGO | S_IWUSR,
|
|
||||||
toshiba_proc_dir,
|
|
||||||
(read_proc_t *) dispatch_read,
|
|
||||||
item);
|
|
||||||
if (proc && item->write_func)
|
|
||||||
proc->write_proc = (write_proc_t *) dispatch_write;
|
|
||||||
}
|
|
||||||
|
|
||||||
return AE_OK;
|
return AE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static acpi_status remove_device(void)
|
static acpi_status remove_device(void)
|
||||||
{
|
{
|
||||||
ProcItem *item;
|
remove_proc_entry("lcd", toshiba_proc_dir);
|
||||||
|
remove_proc_entry("video", toshiba_proc_dir);
|
||||||
for (item = proc_items; item->name; ++item)
|
remove_proc_entry("fan", toshiba_proc_dir);
|
||||||
remove_proc_entry(item->name, toshiba_proc_dir);
|
remove_proc_entry("keys", toshiba_proc_dir);
|
||||||
|
remove_proc_entry("version", toshiba_proc_dir);
|
||||||
return AE_OK;
|
return AE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -540,8 +540,8 @@ EXPORT_SYMBOL_GPL(wmi_remove_notify_handler);
|
||||||
/**
|
/**
|
||||||
* wmi_get_event_data - Get WMI data associated with an event
|
* wmi_get_event_data - Get WMI data associated with an event
|
||||||
*
|
*
|
||||||
* @event - Event to find
|
* @event: Event to find
|
||||||
* &out - Buffer to hold event data
|
* @out: Buffer to hold event data. out->pointer should be freed with kfree()
|
||||||
*
|
*
|
||||||
* Returns extra data associated with an event in WMI.
|
* Returns extra data associated with an event in WMI.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue