* [PATCH 0/4] sony_acpi-0.4: morph into sony-laptop @ 2007-02-07 19:01 malattia 2007-02-07 19:01 ` [PATCH 1/4] Create sony-laptop malattia 0 siblings, 1 reply; 10+ messages in thread From: malattia @ 2007-02-07 19:01 UTC (permalink / raw) To: lenb; +Cc: linux-acpi Hello, the following patches are my current work to move sony_acpi away from drivers/acpi and avoid using /proc to expose the userspace interface in to order to finally see the driver included mainline. (Aaargh! Len, I missed your first batch...) 1/4: will move drivers/acpi/sony_acpi.c to drivers/misc/sony-laptop.c 2/4 to 4/4: implement platform_device and clean up the code Those patches apply on top of the sony-acpi series akpm sent earlier[1] and are developed on the acpi test branch. Thanks -- mattia [1]: [patch 07/13] sony acpi driver [patch 08/13] sony_apci: add resume handling [patch 09/13] acpi: add backlight support to the sony_acpi driver [patch 10/13] sony_acpi: add acpi_bus_generate event [patch 11/13] sony_acpi: add lanpower and audiopower controls [patch 12/13] sony_acpi: allow multiple sony_acpi_values for the same [patch 13/13] sony_acpi: fix sony_acpi backlight registration and unregistration --- b/drivers/acpi/Kconfig | 15 - b/drivers/acpi/Makefile | 1 b/drivers/misc/Kconfig | 15 + b/drivers/misc/Makefile | 1 b/drivers/misc/sony-laptop.c | 514 +++++++++++++++++++++++++++++++++++++++++++ drivers/acpi/sony_acpi.c | 504 ------------------------------------------ 6 files changed, 530 insertions(+), 520 deletions(-) ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/4] Create sony-laptop 2007-02-07 19:01 [PATCH 0/4] sony_acpi-0.4: morph into sony-laptop malattia @ 2007-02-07 19:01 ` malattia 2007-02-07 19:01 ` [PATCH 2/4] Remove /proc/acpi/sony interface and implement platform_device malattia 2007-02-07 20:50 ` [PATCH 1/4] Create sony-laptop Len Brown 0 siblings, 2 replies; 10+ messages in thread From: malattia @ 2007-02-07 19:01 UTC (permalink / raw) To: lenb; +Cc: linux-acpi, Mattia Dongili From: Mattia Dongili <malattia@linux.it> Move drivers/acpi/sony_acpi.c to drivers/misc/sony-laptop.c with all the necessary configuration. The SONY_LAPTOP config option substitutes the old ACPI_SONY and is 'default n' now. Signed-off-by: Mattia Dongili <malattia@linux.it> --- drivers/acpi/Kconfig | 15 -- drivers/acpi/Makefile | 1 - drivers/acpi/sony_acpi.c | 504 -------------------------------------------- drivers/misc/Kconfig | 14 ++ drivers/misc/Makefile | 1 + drivers/misc/sony-laptop.c | 504 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 519 insertions(+), 520 deletions(-) diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 26a8d11..20eacc2 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -277,21 +277,6 @@ config ACPI_TOSHIBA If you have a legacy free Toshiba laptop (such as the Libretto L1 series), say Y. -config ACPI_SONY - tristate "Sony Laptop Extras" - depends on X86 && ACPI - select BACKLIGHT_CLASS_DEVICE - default m - ---help--- - This mini-driver drives the ACPI SNC device present in the - ACPI BIOS of the Sony Vaio laptops. - - It gives access to some extra laptop functionalities. In - its current form, the only thing this driver does is letting - the user set or query the screen brightness. - - Read <file:Documentation/acpi/sony_acpi.txt> for more information. - config ACPI_CUSTOM_DSDT bool "Include Custom DSDT" depends on !STANDALONE diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 20bfe1c..856c32b 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -55,7 +55,6 @@ obj-$(CONFIG_ACPI_THERMAL) += thermal.o obj-$(CONFIG_ACPI_SYSTEM) += system.o event.o obj-$(CONFIG_ACPI_DEBUG) += debug.o obj-$(CONFIG_ACPI_NUMA) += numa.o -obj-$(CONFIG_ACPI_SONY) += sony_acpi.o obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o obj-$(CONFIG_ACPI_IBM) += ibm_acpi.o obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o diff --git a/drivers/acpi/sony_acpi.c b/drivers/acpi/sony_acpi.c deleted file mode 100644 index c01d98d..0000000 --- a/drivers/acpi/sony_acpi.c +++ /dev/null @@ -1,504 +0,0 @@ -/* - * ACPI Sony Notebook Control Driver (SNC) - * - * Copyright (C) 2004-2005 Stelian Pop <stelian@popies.net> - * - * Parts of this driver inspired from asus_acpi.c and ibm_acpi.c - * which are copyrighted by their respective authors. - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/types.h> -#include <linux/backlight.h> -#include <linux/err.h> -#include <acpi/acpi_drivers.h> -#include <acpi/acpi_bus.h> -#include <asm/uaccess.h> - -#define ACPI_SNC_CLASS "sony" -#define ACPI_SNC_HID "SNY5001" -#define ACPI_SNC_DRIVER_NAME "ACPI Sony Notebook Control Driver v0.3" - -/* the device uses 1-based values, while the backlight subsystem uses - 0-based values */ -#define SONY_MAX_BRIGHTNESS 8 - -#define LOG_PFX KERN_WARNING "sony_acpi: " - -MODULE_AUTHOR("Stelian Pop"); -MODULE_DESCRIPTION(ACPI_SNC_DRIVER_NAME); -MODULE_LICENSE("GPL"); - -static int debug; -module_param(debug, int, 0); -MODULE_PARM_DESC(debug, "set this to 1 (and RTFM) if you want to help " - "the development of this driver"); - -static acpi_handle sony_acpi_handle; -static struct proc_dir_entry *sony_acpi_dir; -static struct acpi_device *sony_acpi_acpi_device = NULL; - -static int sony_backlight_update_status(struct backlight_device *bd); -static int sony_backlight_get_brightness(struct backlight_device *bd); -static struct backlight_device *sony_backlight_device; -static struct backlight_properties sony_backlight_properties = { - .owner = THIS_MODULE, - .update_status = sony_backlight_update_status, - .get_brightness = sony_backlight_get_brightness, - .max_brightness = SONY_MAX_BRIGHTNESS - 1, -}; - -static struct sony_acpi_value { - char *name; /* name of the entry */ - struct proc_dir_entry *proc; /* /proc entry */ - char *acpiget;/* name of the ACPI get function */ - char *acpiset;/* name of the ACPI get function */ - int min; /* minimum allowed value or -1 */ - int max; /* maximum allowed value or -1 */ - int value; /* current setting */ - int valid; /* Has ever been set */ - int debug; /* active only in debug mode ? */ -} sony_acpi_values[] = { - { - /* for backward compatibility only */ - .name = "brightness", - .acpiget = "GBRT", - .acpiset = "SBRT", - .min = 1, - .max = SONY_MAX_BRIGHTNESS, - .debug = 0, - }, - { - .name = "brightness_default", - .acpiget = "GPBR", - .acpiset = "SPBR", - .min = 1, - .max = SONY_MAX_BRIGHTNESS, - .debug = 0, - }, - { - .name = "fnkey", - .acpiget = "GHKE", - .debug = 0, - }, - { - .name = "cdpower", - .acpiget = "GCDP", - .acpiset = "SCDP", - .min = 0, - .max = 1, - .debug = 0, - }, - { - .name = "cdpower", - .acpiget = "GCDP", - .acpiset = "CDPW", - .min = 0, - .max = 1, - .debug = 0, - }, - { - .name = "audiopower", - .acpiget = "GAZP", - .acpiset = "AZPW", - .min = 0, - .max = 1, - .debug = 0, - }, - { - .name = "lanpower", - .acpiget = "GLNP", - .acpiset = "LNPW", - .min = 0, - .max = 1, - .debug = 1, - }, - { - .name = "PID", - .acpiget = "GPID", - .debug = 1, - }, - { - .name = "CTR", - .acpiget = "GCTR", - .acpiset = "SCTR", - .min = -1, - .max = -1, - .debug = 1, - }, - { - .name = "PCR", - .acpiget = "GPCR", - .acpiset = "SPCR", - .min = -1, - .max = -1, - .debug = 1, - }, - { - .name = "CMI", - .acpiget = "GCMI", - .acpiset = "SCMI", - .min = -1, - .max = -1, - .debug = 1, - }, - { - .name = NULL, - } -}; - -static int acpi_callgetfunc(acpi_handle handle, char *name, int *result) -{ - struct acpi_buffer output; - union acpi_object out_obj; - acpi_status status; - - output.length = sizeof(out_obj); - output.pointer = &out_obj; - - status = acpi_evaluate_object(handle, name, NULL, &output); - if ((status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER)) { - *result = out_obj.integer.value; - return 0; - } - - printk(LOG_PFX "acpi_callreadfunc failed\n"); - - return -1; -} - -static int acpi_callsetfunc(acpi_handle handle, char *name, int value, - int *result) -{ - struct acpi_object_list params; - union acpi_object in_obj; - struct acpi_buffer output; - union acpi_object out_obj; - acpi_status status; - - params.count = 1; - params.pointer = &in_obj; - in_obj.type = ACPI_TYPE_INTEGER; - in_obj.integer.value = value; - - output.length = sizeof(out_obj); - output.pointer = &out_obj; - - status = acpi_evaluate_object(handle, name, ¶ms, &output); - if (status == AE_OK) { - if (result != NULL) { - if (out_obj.type != ACPI_TYPE_INTEGER) { - printk(LOG_PFX "acpi_evaluate_object bad " - "return type\n"); - return -1; - } - *result = out_obj.integer.value; - } - return 0; - } - - printk(LOG_PFX "acpi_evaluate_object failed\n"); - - return -1; -} - -static int parse_buffer(const char __user *buffer, unsigned long count, - int *val) { - char s[32]; - int ret; - - if (count > 31) - return -EINVAL; - if (copy_from_user(s, buffer, count)) - return -EFAULT; - s[count] = '\0'; - ret = simple_strtoul(s, NULL, 10); - *val = ret; - return 0; -} - -static int sony_acpi_read(char* page, char** start, off_t off, int count, - int* eof, void *data) -{ - struct sony_acpi_value *item = data; - int value; - - if (!item->acpiget) - return -EIO; - - if (acpi_callgetfunc(sony_acpi_handle, item->acpiget, &value) < 0) - return -EIO; - - return sprintf(page, "%d\n", value); -} - -static int sony_acpi_write(struct file *file, const char __user *buffer, - unsigned long count, void *data) -{ - struct sony_acpi_value *item = data; - int result; - int value; - - if (!item->acpiset) - return -EIO; - - if ((result = parse_buffer(buffer, count, &value)) < 0) - return result; - - if (item->min != -1 && value < item->min) - return -EINVAL; - if (item->max != -1 && value > item->max) - return -EINVAL; - - if (acpi_callsetfunc(sony_acpi_handle, item->acpiset, value, NULL) < 0) - return -EIO; - item->value = value; - item->valid = 1; - return count; -} - -static int sony_acpi_resume(struct acpi_device *device) -{ - struct sony_acpi_value *item; - - for (item = sony_acpi_values; item->name; item++) { - int ret; - - if (!item->valid) - continue; - ret = acpi_callsetfunc(sony_acpi_handle, item->acpiset, - item->value, NULL); - if (ret < 0) { - printk("%s: %d\n", __FUNCTION__, ret); - break; - } - } - return 0; -} - -static void sony_acpi_notify(acpi_handle handle, u32 event, void *data) -{ - if (debug) - printk(LOG_PFX "sony_acpi_notify, event: %d\n", event); - acpi_bus_generate_event(sony_acpi_acpi_device, 1, event); -} - -static acpi_status sony_walk_callback(acpi_handle handle, u32 level, - void *context, void **return_value) -{ - struct acpi_namespace_node *node; - union acpi_operand_object *operand; - - node = (struct acpi_namespace_node *) handle; - operand = (union acpi_operand_object *) node->object; - - printk(LOG_PFX "method: name: %4.4s, args %X\n", node->name.ascii, - (u32) operand->method.param_count); - - return AE_OK; -} - -static int sony_acpi_add(struct acpi_device *device) -{ - acpi_status status; - int result; - acpi_handle handle; - mode_t proc_file_mode; - struct sony_acpi_value *item; - - sony_acpi_acpi_device = device; - - sony_acpi_handle = device->handle; - - acpi_driver_data(device) = NULL; - acpi_device_dir(device) = sony_acpi_dir; - - if (debug) { - status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_acpi_handle, - 1, sony_walk_callback, NULL, NULL); - if (ACPI_FAILURE(status)) { - printk(LOG_PFX "unable to walk acpi resources\n"); - result = -ENODEV; - goto outwalk; - } - } - - status = acpi_install_notify_handler(sony_acpi_handle, - ACPI_DEVICE_NOTIFY, - sony_acpi_notify, - NULL); - if (ACPI_FAILURE(status)) { - printk(LOG_PFX "unable to install notify handler\n"); - result = -ENODEV; - goto outnotify; - } - - if (ACPI_SUCCESS(acpi_get_handle(sony_acpi_handle, "GBRT", &handle))) { - sony_backlight_device = backlight_device_register("sony", NULL, - NULL, &sony_backlight_properties); - - if (IS_ERR(sony_backlight_device)) { - printk(LOG_PFX "unable to register backlight device\n"); - sony_backlight_device = NULL; - } - else - sony_backlight_properties.brightness = - sony_backlight_get_brightness(sony_backlight_device); - } - - for (item = sony_acpi_values; item->name; ++item) { - proc_file_mode = 0; - - if (!debug && item->debug) - continue; - - if (item->acpiget) { - if (ACPI_FAILURE(acpi_get_handle(sony_acpi_handle, - item->acpiget, &handle))) - continue; - - proc_file_mode |= S_IRUSR; - } - - if (item->acpiset) { - if (ACPI_FAILURE(acpi_get_handle(sony_acpi_handle, - item->acpiset, &handle))) - continue; - - proc_file_mode |= S_IWUSR; - } - - item->proc = create_proc_entry(item->name, proc_file_mode, - acpi_device_dir(device)); - if (!item->proc) { - printk(LOG_PFX "unable to create proc entry\n"); - result = -EIO; - goto outproc; - } - - item->proc->read_proc = sony_acpi_read; - item->proc->write_proc = sony_acpi_write; - item->proc->data = item; - item->proc->owner = THIS_MODULE; - } - - printk(KERN_INFO ACPI_SNC_DRIVER_NAME " successfully installed\n"); - - return 0; - -outproc: - if (sony_backlight_device) - backlight_device_unregister(sony_backlight_device); - - for (item = sony_acpi_values; item->name; ++item) - if (item->proc) - remove_proc_entry(item->name, acpi_device_dir(device)); -outnotify: - status = acpi_remove_notify_handler(sony_acpi_handle, - ACPI_DEVICE_NOTIFY, - sony_acpi_notify); - if (ACPI_FAILURE(status)) - printk(LOG_PFX "unable to remove notify handler\n"); -outwalk: - return result; -} - -static int sony_acpi_remove(struct acpi_device *device, int type) -{ - acpi_status status; - struct sony_acpi_value *item; - - if (sony_backlight_device) - backlight_device_unregister(sony_backlight_device); - - sony_acpi_acpi_device = NULL; - - status = acpi_remove_notify_handler(sony_acpi_handle, - ACPI_DEVICE_NOTIFY, - sony_acpi_notify); - if (ACPI_FAILURE(status)) - printk(LOG_PFX "unable to remove notify handler\n"); - - for (item = sony_acpi_values; item->name; ++item) - if (item->proc) - remove_proc_entry(item->name, acpi_device_dir(device)); - - printk(KERN_INFO ACPI_SNC_DRIVER_NAME " successfully removed\n"); - - return 0; -} - -static int sony_backlight_update_status(struct backlight_device *bd) -{ - return acpi_callsetfunc(sony_acpi_handle, "SBRT", - bd->props->brightness + 1, - NULL); -} - -static int sony_backlight_get_brightness(struct backlight_device *bd) -{ - int value; - - if (acpi_callgetfunc(sony_acpi_handle, "GBRT", &value)) - return 0; - /* brightness levels are 1-based, while backlight ones are 0-based */ - return value - 1; -} - -static struct acpi_driver sony_acpi_driver = { - .name = ACPI_SNC_DRIVER_NAME, - .class = ACPI_SNC_CLASS, - .ids = ACPI_SNC_HID, - .ops = { - .add = sony_acpi_add, - .remove = sony_acpi_remove, - .resume = sony_acpi_resume, - }, -}; - -static int __init sony_acpi_init(void) -{ - int result; - - sony_acpi_dir = proc_mkdir("sony", acpi_root_dir); - if (!sony_acpi_dir) { - printk(LOG_PFX "unable to create /proc entry\n"); - return -ENODEV; - } - sony_acpi_dir->owner = THIS_MODULE; - - result = acpi_bus_register_driver(&sony_acpi_driver); - if (result < 0) { - remove_proc_entry("sony", acpi_root_dir); - return -ENODEV; - } - return 0; -} - - -static void __exit sony_acpi_exit(void) -{ - acpi_bus_unregister_driver(&sony_acpi_driver); - remove_proc_entry("sony", acpi_root_dir); -} - -module_init(sony_acpi_init); -module_exit(sony_acpi_exit); diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 89bba27..4acd922 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -107,4 +107,18 @@ config MSI_LAPTOP If you have an MSI S270 laptop, say Y or M here. +config SONY_LAPTOP + tristate "Sony Laptop Extras" + depends on X86 && ACPI + select BACKLIGHT_CLASS_DEVICE + ---help--- + This mini-driver drives the ACPI SNC device present in the + ACPI BIOS of the Sony Vaio laptops. + + It gives access to some extra laptop functionalities. In + its current form, the only thing this driver does is letting + the user set or query the screen brightness. + + Read <file:Documentation/acpi/sony_acpi.txt> for more information. + endmenu diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 35da53c..7793ccd 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_LKDTM) += lkdtm.o obj-$(CONFIG_TIFM_CORE) += tifm_core.o obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o obj-$(CONFIG_SGI_IOC4) += ioc4.o +obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c new file mode 100644 index 0000000..103657e --- /dev/null +++ b/drivers/misc/sony-laptop.c @@ -0,0 +1,504 @@ +/* + * ACPI Sony Notebook Control Driver (SNC) + * + * Copyright (C) 2004-2005 Stelian Pop <stelian@popies.net> + * + * Parts of this driver inspired from asus_acpi.c and ibm_acpi.c + * which are copyrighted by their respective authors. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/init.h> +#include <linux/types.h> +#include <linux/backlight.h> +#include <linux/err.h> +#include <acpi/acpi_drivers.h> +#include <acpi/acpi_bus.h> +#include <asm/uaccess.h> + +#define ACPI_SNC_CLASS "sony" +#define ACPI_SNC_HID "SNY5001" +#define ACPI_SNC_DRIVER_NAME "ACPI Sony Notebook Control Driver v0.3" + +/* the device uses 1-based values, while the backlight subsystem uses + 0-based values */ +#define SONY_MAX_BRIGHTNESS 8 + +#define LOG_PFX KERN_WARNING "sony_acpi: " + +MODULE_AUTHOR("Stelian Pop"); +MODULE_DESCRIPTION(ACPI_SNC_DRIVER_NAME); +MODULE_LICENSE("GPL"); + +static int debug; +module_param(debug, int, 0); +MODULE_PARM_DESC(debug, "set this to 1 (and RTFM) if you want to help " + "the development of this driver"); + +static acpi_handle sony_acpi_handle; +static struct proc_dir_entry *sony_acpi_dir; +static struct acpi_device *sony_acpi_acpi_device = NULL; + +static int sony_backlight_update_status(struct backlight_device *bd); +static int sony_backlight_get_brightness(struct backlight_device *bd); +static struct backlight_device *sony_backlight_device; +static struct backlight_properties sony_backlight_properties = { + .owner = THIS_MODULE, + .update_status = sony_backlight_update_status, + .get_brightness = sony_backlight_get_brightness, + .max_brightness = SONY_MAX_BRIGHTNESS - 1, +}; + +static struct sony_acpi_value { + char *name; /* name of the entry */ + struct proc_dir_entry *proc; /* /proc entry */ + char *acpiget;/* name of the ACPI get function */ + char *acpiset;/* name of the ACPI get function */ + int min; /* minimum allowed value or -1 */ + int max; /* maximum allowed value or -1 */ + int value; /* current setting */ + int valid; /* Has ever been set */ + int debug; /* active only in debug mode ? */ +} sony_acpi_values[] = { + { + /* for backward compatibility only */ + .name = "brightness", + .acpiget = "GBRT", + .acpiset = "SBRT", + .min = 1, + .max = SONY_MAX_BRIGHTNESS, + .debug = 0, + }, + { + .name = "brightness_default", + .acpiget = "GPBR", + .acpiset = "SPBR", + .min = 1, + .max = SONY_MAX_BRIGHTNESS, + .debug = 0, + }, + { + .name = "fnkey", + .acpiget = "GHKE", + .debug = 0, + }, + { + .name = "cdpower", + .acpiget = "GCDP", + .acpiset = "SCDP", + .min = 0, + .max = 1, + .debug = 0, + }, + { + .name = "cdpower", + .acpiget = "GCDP", + .acpiset = "CDPW", + .min = 0, + .max = 1, + .debug = 0, + }, + { + .name = "audiopower", + .acpiget = "GAZP", + .acpiset = "AZPW", + .min = 0, + .max = 1, + .debug = 0, + }, + { + .name = "lanpower", + .acpiget = "GLNP", + .acpiset = "LNPW", + .min = 0, + .max = 1, + .debug = 1, + }, + { + .name = "PID", + .acpiget = "GPID", + .debug = 1, + }, + { + .name = "CTR", + .acpiget = "GCTR", + .acpiset = "SCTR", + .min = -1, + .max = -1, + .debug = 1, + }, + { + .name = "PCR", + .acpiget = "GPCR", + .acpiset = "SPCR", + .min = -1, + .max = -1, + .debug = 1, + }, + { + .name = "CMI", + .acpiget = "GCMI", + .acpiset = "SCMI", + .min = -1, + .max = -1, + .debug = 1, + }, + { + .name = NULL, + } +}; + +static int acpi_callgetfunc(acpi_handle handle, char *name, int *result) +{ + struct acpi_buffer output; + union acpi_object out_obj; + acpi_status status; + + output.length = sizeof(out_obj); + output.pointer = &out_obj; + + status = acpi_evaluate_object(handle, name, NULL, &output); + if ((status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER)) { + *result = out_obj.integer.value; + return 0; + } + + printk(LOG_PFX "acpi_callreadfunc failed\n"); + + return -1; +} + +static int acpi_callsetfunc(acpi_handle handle, char *name, int value, + int *result) +{ + struct acpi_object_list params; + union acpi_object in_obj; + struct acpi_buffer output; + union acpi_object out_obj; + acpi_status status; + + params.count = 1; + params.pointer = &in_obj; + in_obj.type = ACPI_TYPE_INTEGER; + in_obj.integer.value = value; + + output.length = sizeof(out_obj); + output.pointer = &out_obj; + + status = acpi_evaluate_object(handle, name, ¶ms, &output); + if (status == AE_OK) { + if (result != NULL) { + if (out_obj.type != ACPI_TYPE_INTEGER) { + printk(LOG_PFX "acpi_evaluate_object bad " + "return type\n"); + return -1; + } + *result = out_obj.integer.value; + } + return 0; + } + + printk(LOG_PFX "acpi_evaluate_object failed\n"); + + return -1; +} + +static int parse_buffer(const char __user *buffer, unsigned long count, + int *val) { + char s[32]; + int ret; + + if (count > 31) + return -EINVAL; + if (copy_from_user(s, buffer, count)) + return -EFAULT; + s[count] = '\0'; + ret = simple_strtoul(s, NULL, 10); + *val = ret; + return 0; +} + +static int sony_acpi_read(char* page, char** start, off_t off, int count, + int* eof, void *data) +{ + struct sony_acpi_value *item = data; + int value; + + if (!item->acpiget) + return -EIO; + + if (acpi_callgetfunc(sony_acpi_handle, item->acpiget, &value) < 0) + return -EIO; + + return sprintf(page, "%d\n", value); +} + +static int sony_acpi_write(struct file *file, const char __user *buffer, + unsigned long count, void *data) +{ + struct sony_acpi_value *item = data; + int result; + int value; + + if (!item->acpiset) + return -EIO; + + if ((result = parse_buffer(buffer, count, &value)) < 0) + return result; + + if (item->min != -1 && value < item->min) + return -EINVAL; + if (item->max != -1 && value > item->max) + return -EINVAL; + + if (acpi_callsetfunc(sony_acpi_handle, item->acpiset, value, NULL) < 0) + return -EIO; + item->value = value; + item->valid = 1; + return count; +} + +static int sony_acpi_resume(struct acpi_device *device) +{ + struct sony_acpi_value *item; + + for (item = sony_acpi_values; item->name; item++) { + int ret; + + if (!item->valid) + continue; + ret = acpi_callsetfunc(sony_acpi_handle, item->acpiset, + item->value, NULL); + if (ret < 0) { + printk("%s: %d\n", __FUNCTION__, ret); + break; + } + } + return 0; +} + +static void sony_acpi_notify(acpi_handle handle, u32 event, void *data) +{ + if (debug) + printk(LOG_PFX "sony_acpi_notify, event: %d\n", event); + acpi_bus_generate_event(sony_acpi_acpi_device, 1, event); +} + +static acpi_status sony_walk_callback(acpi_handle handle, u32 level, + void *context, void **return_value) +{ + struct acpi_namespace_node *node; + union acpi_operand_object *operand; + + node = (struct acpi_namespace_node *) handle; + operand = (union acpi_operand_object *) node->object; + + printk(LOG_PFX "method: name: %4.4s, args %X\n", node->name.ascii, + (u32) operand->method.param_count); + + return AE_OK; +} + +static int sony_acpi_add(struct acpi_device *device) +{ + acpi_status status; + int result; + acpi_handle handle; + mode_t proc_file_mode; + struct sony_acpi_value *item; + + sony_acpi_acpi_device = device; + + sony_acpi_handle = device->handle; + + acpi_driver_data(device) = NULL; + acpi_device_dir(device) = sony_acpi_dir; + + if (debug) { + status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_acpi_handle, + 1, sony_walk_callback, NULL, NULL); + if (ACPI_FAILURE(status)) { + printk(LOG_PFX "unable to walk acpi resources\n"); + result = -ENODEV; + goto outwalk; + } + } + + status = acpi_install_notify_handler(sony_acpi_handle, + ACPI_DEVICE_NOTIFY, + sony_acpi_notify, + NULL); + if (ACPI_FAILURE(status)) { + printk(LOG_PFX "unable to install notify handler\n"); + result = -ENODEV; + goto outnotify; + } + + if (ACPI_SUCCESS(acpi_get_handle(sony_acpi_handle, "GBRT", &handle))) { + sony_backlight_device = backlight_device_register("sony", NULL, + NULL, &sony_backlight_properties); + + if (IS_ERR(sony_backlight_device)) { + printk(LOG_PFX "unable to register backlight device\n"); + sony_backlight_device = NULL; + } + else + sony_backlight_properties.brightness = + sony_backlight_get_brightness(sony_backlight_device); + } + + for (item = sony_acpi_values; item->name; ++item) { + proc_file_mode = 0; + + if (!debug && item->debug) + continue; + + if (item->acpiget) { + if (ACPI_FAILURE(acpi_get_handle(sony_acpi_handle, + item->acpiget, &handle))) + continue; + + proc_file_mode |= S_IRUSR; + } + + if (item->acpiset) { + if (ACPI_FAILURE(acpi_get_handle(sony_acpi_handle, + item->acpiset, &handle))) + continue; + + proc_file_mode |= S_IWUSR; + } + + item->proc = create_proc_entry(item->name, proc_file_mode, + acpi_device_dir(device)); + if (!item->proc) { + printk(LOG_PFX "unable to create proc entry\n"); + result = -EIO; + goto outproc; + } + + item->proc->read_proc = sony_acpi_read; + item->proc->write_proc = sony_acpi_write; + item->proc->data = item; + item->proc->owner = THIS_MODULE; + } + + printk(KERN_INFO ACPI_SNC_DRIVER_NAME " successfully installed\n"); + + return 0; + +outproc: + if (sony_backlight_device) + backlight_device_unregister(sony_backlight_device); + + for (item = sony_acpi_values; item->name; ++item) + if (item->proc) + remove_proc_entry(item->name, acpi_device_dir(device)); +outnotify: + status = acpi_remove_notify_handler(sony_acpi_handle, + ACPI_DEVICE_NOTIFY, + sony_acpi_notify); + if (ACPI_FAILURE(status)) + printk(LOG_PFX "unable to remove notify handler\n"); +outwalk: + return result; +} + +static int sony_acpi_remove(struct acpi_device *device, int type) +{ + acpi_status status; + struct sony_acpi_value *item; + + if (sony_backlight_device) + backlight_device_unregister(sony_backlight_device); + + sony_acpi_acpi_device = NULL; + + status = acpi_remove_notify_handler(sony_acpi_handle, + ACPI_DEVICE_NOTIFY, + sony_acpi_notify); + if (ACPI_FAILURE(status)) + printk(LOG_PFX "unable to remove notify handler\n"); + + for (item = sony_acpi_values; item->name; ++item) + if (item->proc) + remove_proc_entry(item->name, acpi_device_dir(device)); + + printk(KERN_INFO ACPI_SNC_DRIVER_NAME " successfully removed\n"); + + return 0; +} + +static int sony_backlight_update_status(struct backlight_device *bd) +{ + return acpi_callsetfunc(sony_acpi_handle, "SBRT", + bd->props->brightness + 1, + NULL); +} + +static int sony_backlight_get_brightness(struct backlight_device *bd) +{ + int value; + + if (acpi_callgetfunc(sony_acpi_handle, "GBRT", &value)) + return 0; + /* brightness levels are 1-based, while backlight ones are 0-based */ + return value - 1; +} + +static struct acpi_driver sony_acpi_driver = { + .name = ACPI_SNC_DRIVER_NAME, + .class = ACPI_SNC_CLASS, + .ids = ACPI_SNC_HID, + .ops = { + .add = sony_acpi_add, + .remove = sony_acpi_remove, + .resume = sony_acpi_resume, + }, +}; + +static int __init sony_acpi_init(void) +{ + int result; + + sony_acpi_dir = proc_mkdir("sony", acpi_root_dir); + if (!sony_acpi_dir) { + printk(LOG_PFX "unable to create /proc entry\n"); + return -ENODEV; + } + sony_acpi_dir->owner = THIS_MODULE; + + result = acpi_bus_register_driver(&sony_acpi_driver); + if (result < 0) { + remove_proc_entry("sony", acpi_root_dir); + return -ENODEV; + } + return 0; +} + + +static void __exit sony_acpi_exit(void) +{ + acpi_bus_unregister_driver(&sony_acpi_driver); + remove_proc_entry("sony", acpi_root_dir); +} + +module_init(sony_acpi_init); +module_exit(sony_acpi_exit); -- 1.4.4.3 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/4] Remove /proc/acpi/sony interface and implement platform_device. 2007-02-07 19:01 ` [PATCH 1/4] Create sony-laptop malattia @ 2007-02-07 19:01 ` malattia 2007-02-07 19:01 ` [PATCH 3/4] Small update to the Kconfig help to make people believe this driver is useful malattia 2007-02-10 1:47 ` [PATCH 2/4] Remove /proc/acpi/sony interface and implement platform_device Alessandro Guido 2007-02-07 20:50 ` [PATCH 1/4] Create sony-laptop Len Brown 1 sibling, 2 replies; 10+ messages in thread From: malattia @ 2007-02-07 19:01 UTC (permalink / raw) To: lenb; +Cc: linux-acpi, Mattia Dongili From: Mattia Dongili <malattia@linux.it> Rework method names list to allow an easier management of multiple values. Add myself as author/maintainer and bump the version number. Signed-off-by: Mattia Dongili <malattia@linux.it> --- drivers/misc/sony-laptop.c | 396 ++++++++++++++++++++++---------------------- 1 files changed, 198 insertions(+), 198 deletions(-) diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c index 103657e..1d14969 100644 --- a/drivers/misc/sony-laptop.c +++ b/drivers/misc/sony-laptop.c @@ -2,6 +2,7 @@ * ACPI Sony Notebook Control Driver (SNC) * * Copyright (C) 2004-2005 Stelian Pop <stelian@popies.net> + * Copyright (C) 2007 Mattia Dongili <malattia@linux.it> * * Parts of this driver inspired from asus_acpi.c and ibm_acpi.c * which are copyrighted by their respective authors. @@ -28,6 +29,7 @@ #include <linux/init.h> #include <linux/types.h> #include <linux/backlight.h> +#include <linux/platform_device.h> #include <linux/err.h> #include <acpi/acpi_drivers.h> #include <acpi/acpi_bus.h> @@ -35,15 +37,15 @@ #define ACPI_SNC_CLASS "sony" #define ACPI_SNC_HID "SNY5001" -#define ACPI_SNC_DRIVER_NAME "ACPI Sony Notebook Control Driver v0.3" +#define ACPI_SNC_DRIVER_NAME "ACPI Sony Notebook Control Driver v0.4" /* the device uses 1-based values, while the backlight subsystem uses 0-based values */ #define SONY_MAX_BRIGHTNESS 8 -#define LOG_PFX KERN_WARNING "sony_acpi: " +#define LOG_PFX KERN_WARNING "sony-laptop: " -MODULE_AUTHOR("Stelian Pop"); +MODULE_AUTHOR("Stelian Pop, Mattia Dongili"); MODULE_DESCRIPTION(ACPI_SNC_DRIVER_NAME); MODULE_LICENSE("GPL"); @@ -52,10 +54,6 @@ module_param(debug, int, 0); MODULE_PARM_DESC(debug, "set this to 1 (and RTFM) if you want to help " "the development of this driver"); -static acpi_handle sony_acpi_handle; -static struct proc_dir_entry *sony_acpi_dir; -static struct acpi_device *sony_acpi_acpi_device = NULL; - static int sony_backlight_update_status(struct backlight_device *bd); static int sony_backlight_get_brightness(struct backlight_device *bd); static struct backlight_device *sony_backlight_device; @@ -66,105 +64,79 @@ static struct backlight_properties sony_backlight_properties = { .max_brightness = SONY_MAX_BRIGHTNESS - 1, }; -static struct sony_acpi_value { - char *name; /* name of the entry */ - struct proc_dir_entry *proc; /* /proc entry */ - char *acpiget;/* name of the ACPI get function */ - char *acpiset;/* name of the ACPI get function */ - int min; /* minimum allowed value or -1 */ - int max; /* maximum allowed value or -1 */ - int value; /* current setting */ - int valid; /* Has ever been set */ - int debug; /* active only in debug mode ? */ -} sony_acpi_values[] = { - { - /* for backward compatibility only */ - .name = "brightness", - .acpiget = "GBRT", - .acpiset = "SBRT", - .min = 1, - .max = SONY_MAX_BRIGHTNESS, - .debug = 0, - }, - { - .name = "brightness_default", - .acpiget = "GPBR", - .acpiset = "SPBR", - .min = 1, - .max = SONY_MAX_BRIGHTNESS, - .debug = 0, - }, - { - .name = "fnkey", - .acpiget = "GHKE", - .debug = 0, - }, - { - .name = "cdpower", - .acpiget = "GCDP", - .acpiset = "SCDP", - .min = 0, - .max = 1, - .debug = 0, - }, - { - .name = "cdpower", - .acpiget = "GCDP", - .acpiset = "CDPW", - .min = 0, - .max = 1, - .debug = 0, - }, - { - .name = "audiopower", - .acpiget = "GAZP", - .acpiset = "AZPW", - .min = 0, - .max = 1, - .debug = 0, - }, - { - .name = "lanpower", - .acpiget = "GLNP", - .acpiset = "LNPW", - .min = 0, - .max = 1, - .debug = 1, - }, - { - .name = "PID", - .acpiget = "GPID", - .debug = 1, - }, - { - .name = "CTR", - .acpiget = "GCTR", - .acpiset = "SCTR", - .min = -1, - .max = -1, - .debug = 1, - }, - { - .name = "PCR", - .acpiget = "GPCR", - .acpiset = "SPCR", - .min = -1, - .max = -1, - .debug = 1, - }, - { - .name = "CMI", - .acpiget = "GCMI", - .acpiset = "SCMI", - .min = -1, - .max = -1, - .debug = 1, - }, - { - .name = NULL, +static ssize_t sony_acpi_show(struct device *, struct device_attribute *, char *); +static ssize_t sony_acpi_store(struct device *, struct device_attribute *, const char *, size_t); + +struct sony_acpi_value { + char *name; /* name of the entry */ + char **acpiget; /* names of the ACPI get function */ + char **acpiset; /* names of the ACPI set function */ + int min; /* minimum allowed value or -1 */ + int max; /* maximum allowed value or -1 */ + int value; /* current setting */ + int valid; /* Has ever been set */ + int debug; /* active only in debug mode ? */ + struct device_attribute devattr; /* sysfs atribute */ +}; + +#define HANDLE_NAMES(_name, _values...) \ + static char *snc_##_name[] = { _values, NULL } + +#define SONY_ACPI_VALUE(_name, _getters, _setters, _min, _max, _debug) \ + { \ + .name = __stringify(_name), \ + .acpiget = _getters, \ + .acpiset = _setters, \ + .min = _min, \ + .max = _max, \ + .debug = _debug, \ + .devattr = __ATTR(_name, 0, sony_acpi_show, sony_acpi_store), \ } + +#define SONY_ACPI_VALUE_NULL { .name = NULL } + +HANDLE_NAMES(fnkey_get, "GHKE"); + +HANDLE_NAMES(brightness_def_get, "GPBR"); +HANDLE_NAMES(brightness_def_set, "SPBR"); + +HANDLE_NAMES(cdpower_get, "GCDP"); +HANDLE_NAMES(cdpower_set, "SCDP", "CDPW"); + +HANDLE_NAMES(audiopower_get, "GAZP"); +HANDLE_NAMES(audiopower_set, "AZPW"); + +HANDLE_NAMES(lanpower_get, "GLNP"); +HANDLE_NAMES(lanpower_set, "LNPW"); + +HANDLE_NAMES(PID_get, "GPID"); + +HANDLE_NAMES(CTR_get, "GCTR"); +HANDLE_NAMES(CTR_set, "SCTR"); + +HANDLE_NAMES(PCR_get, "GPCR"); +HANDLE_NAMES(PCR_set, "SPCR"); + +HANDLE_NAMES(CMI_get, "GCMI"); +HANDLE_NAMES(CMI_set, "SCMI"); + +static struct sony_acpi_value sony_acpi_values[] = { + SONY_ACPI_VALUE(brightness_default, snc_brightness_def_get, snc_brightness_def_set, 1, SONY_MAX_BRIGHTNESS, 0), + SONY_ACPI_VALUE(fnkey, snc_fnkey_get, NULL, -1, -1, 0), + SONY_ACPI_VALUE(cdpower, snc_cdpower_get, snc_cdpower_set, 0, 1, 0), + SONY_ACPI_VALUE(audiopower, snc_audiopower_get, snc_audiopower_set, 0, 1, 0), + SONY_ACPI_VALUE(lanpower, snc_lanpower_get, snc_lanpower_set, 0, 1, 1), + /* unknown methods */ + SONY_ACPI_VALUE(PID, snc_PID_get, NULL, -1, -1, 1), + SONY_ACPI_VALUE(CTR, snc_CTR_get, snc_CTR_set, -1, -1, 1), + SONY_ACPI_VALUE(PCR, snc_PCR_get, snc_PCR_set, -1, -1, 1), + SONY_ACPI_VALUE(CMI, snc_CMI_get, snc_CMI_set, -1, -1, 1), + SONY_ACPI_VALUE_NULL }; +static acpi_handle sony_acpi_handle; +static struct acpi_device *sony_acpi_acpi_device = NULL; + static int acpi_callgetfunc(acpi_handle handle, char *name, int *result) { struct acpi_buffer output; @@ -220,61 +192,149 @@ static int acpi_callsetfunc(acpi_handle handle, char *name, int value, return -1; } -static int parse_buffer(const char __user *buffer, unsigned long count, - int *val) { - char s[32]; - int ret; - - if (count > 31) - return -EINVAL; - if (copy_from_user(s, buffer, count)) - return -EFAULT; - s[count] = '\0'; - ret = simple_strtoul(s, NULL, 10); - *val = ret; - return 0; -} - -static int sony_acpi_read(char* page, char** start, off_t off, int count, - int* eof, void *data) +/* + * Sysfs show/store common to all sony_acpi_values + */ +static ssize_t sony_acpi_show(struct device *dev, struct device_attribute *attr, + char *buffer) { - struct sony_acpi_value *item = data; int value; + struct sony_acpi_value *item = container_of(attr, struct sony_acpi_value, devattr); - if (!item->acpiget) + if (!*item->acpiget) return -EIO; - if (acpi_callgetfunc(sony_acpi_handle, item->acpiget, &value) < 0) + if (acpi_callgetfunc(sony_acpi_handle, *item->acpiget, &value) < 0) return -EIO; - return sprintf(page, "%d\n", value); + return snprintf(buffer, PAGE_SIZE, "%d\n", value); } -static int sony_acpi_write(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static ssize_t sony_acpi_store(struct device *dev, struct device_attribute *attr, + const char *buffer, size_t count) { - struct sony_acpi_value *item = data; - int result; int value; + struct sony_acpi_value *item = container_of(attr, struct sony_acpi_value, devattr); if (!item->acpiset) return -EIO; - if ((result = parse_buffer(buffer, count, &value)) < 0) - return result; + if (count > 31) + return -EINVAL; + + value = simple_strtoul(buffer, NULL, 10); if (item->min != -1 && value < item->min) return -EINVAL; if (item->max != -1 && value > item->max) return -EINVAL; - if (acpi_callsetfunc(sony_acpi_handle, item->acpiset, value, NULL) < 0) + if (acpi_callsetfunc(sony_acpi_handle, *item->acpiset, value, NULL) < 0) return -EIO; item->value = value; item->valid = 1; return count; } +/* + * Platform device + */ +static struct platform_driver sncpf_driver = { + .driver = { + .name = "sony-laptop", + .owner = THIS_MODULE, + } +}; +static struct platform_device *sncpf_device; + +static int sony_snc_pf_add(void) +{ + acpi_handle handle; + struct sony_acpi_value *item; + int ret = 0; + + ret = platform_driver_register(&sncpf_driver); + if (ret) + goto out; + + sncpf_device = platform_device_alloc("sony-laptop", -1); + if (!sncpf_device) { + ret = -ENOMEM; + goto out_platform_registered; + } + + ret = platform_device_add(sncpf_device); + if (ret) + goto out_platform_alloced; + + for (item = sony_acpi_values; item->name; ++item) { + + if (!debug && item->debug) + continue; + + /* find the available acpiget as described in the DSDT */ + for (; item->acpiget && *item->acpiget; ++item->acpiget) { + if (ACPI_SUCCESS(acpi_get_handle(sony_acpi_handle, + *item->acpiget, + &handle))) { + if (debug) + printk(LOG_PFX "Found %s getter: %s\n", + item->name, + *item->acpiget); + item->devattr.attr.mode |= S_IRUGO; + break; + } + } + + /* find the available acpiset as described in the DSDT */ + for (; item->acpiset && *item->acpiset; ++item->acpiset) { + if (ACPI_SUCCESS(acpi_get_handle(sony_acpi_handle, + *item->acpiset, + &handle))) { + if (debug) + printk(LOG_PFX "Found %s setter: %s\n", + item->name, + *item->acpiset); + item->devattr.attr.mode |= S_IWUSR; + break; + } + } + + if (item->devattr.attr.mode != 0) { + ret = device_create_file(&sncpf_device->dev, &item->devattr); + if (ret) + goto out_sysfs; + } + } + + return 0; + +out_sysfs: + for (item = sony_acpi_values; item->name; ++item) { + device_remove_file(&sncpf_device->dev, &item->devattr); + } + platform_device_del(sncpf_device); +out_platform_alloced: + platform_device_put(sncpf_device); +out_platform_registered: + platform_driver_unregister(&sncpf_driver); +out: + return ret; +} + +static void sony_snc_pf_remove(void) +{ + struct sony_acpi_value *item; + + for (item = sony_acpi_values; item->name; ++item) { + device_remove_file(&sncpf_device->dev, &item->devattr); + } + + platform_device_del(sncpf_device); + platform_device_put(sncpf_device); + platform_driver_unregister(&sncpf_driver); +} + static int sony_acpi_resume(struct acpi_device *device) { struct sony_acpi_value *item; @@ -284,7 +344,7 @@ static int sony_acpi_resume(struct acpi_device *device) if (!item->valid) continue; - ret = acpi_callsetfunc(sony_acpi_handle, item->acpiset, + ret = acpi_callsetfunc(sony_acpi_handle, *item->acpiset, item->value, NULL); if (ret < 0) { printk("%s: %d\n", __FUNCTION__, ret); @@ -321,16 +381,11 @@ static int sony_acpi_add(struct acpi_device *device) acpi_status status; int result; acpi_handle handle; - mode_t proc_file_mode; - struct sony_acpi_value *item; sony_acpi_acpi_device = device; sony_acpi_handle = device->handle; - acpi_driver_data(device) = NULL; - acpi_device_dir(device) = sony_acpi_dir; - if (debug) { status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_acpi_handle, 1, sony_walk_callback, NULL, NULL); @@ -348,7 +403,7 @@ static int sony_acpi_add(struct acpi_device *device) if (ACPI_FAILURE(status)) { printk(LOG_PFX "unable to install notify handler\n"); result = -ENODEV; - goto outnotify; + goto outwalk; } if (ACPI_SUCCESS(acpi_get_handle(sony_acpi_handle, "GBRT", &handle))) { @@ -364,54 +419,17 @@ static int sony_acpi_add(struct acpi_device *device) sony_backlight_get_brightness(sony_backlight_device); } - for (item = sony_acpi_values; item->name; ++item) { - proc_file_mode = 0; - - if (!debug && item->debug) - continue; - - if (item->acpiget) { - if (ACPI_FAILURE(acpi_get_handle(sony_acpi_handle, - item->acpiget, &handle))) - continue; - - proc_file_mode |= S_IRUSR; - } - - if (item->acpiset) { - if (ACPI_FAILURE(acpi_get_handle(sony_acpi_handle, - item->acpiset, &handle))) - continue; - - proc_file_mode |= S_IWUSR; - } - - item->proc = create_proc_entry(item->name, proc_file_mode, - acpi_device_dir(device)); - if (!item->proc) { - printk(LOG_PFX "unable to create proc entry\n"); - result = -EIO; - goto outproc; - } - - item->proc->read_proc = sony_acpi_read; - item->proc->write_proc = sony_acpi_write; - item->proc->data = item; - item->proc->owner = THIS_MODULE; - } + if (sony_snc_pf_add()) + goto outbacklight; printk(KERN_INFO ACPI_SNC_DRIVER_NAME " successfully installed\n"); return 0; -outproc: +outbacklight: if (sony_backlight_device) backlight_device_unregister(sony_backlight_device); - for (item = sony_acpi_values; item->name; ++item) - if (item->proc) - remove_proc_entry(item->name, acpi_device_dir(device)); -outnotify: status = acpi_remove_notify_handler(sony_acpi_handle, ACPI_DEVICE_NOTIFY, sony_acpi_notify); @@ -424,7 +442,6 @@ outwalk: static int sony_acpi_remove(struct acpi_device *device, int type) { acpi_status status; - struct sony_acpi_value *item; if (sony_backlight_device) backlight_device_unregister(sony_backlight_device); @@ -437,9 +454,7 @@ static int sony_acpi_remove(struct acpi_device *device, int type) if (ACPI_FAILURE(status)) printk(LOG_PFX "unable to remove notify handler\n"); - for (item = sony_acpi_values; item->name; ++item) - if (item->proc) - remove_proc_entry(item->name, acpi_device_dir(device)); + sony_snc_pf_remove(); printk(KERN_INFO ACPI_SNC_DRIVER_NAME " successfully removed\n"); @@ -476,28 +491,13 @@ static struct acpi_driver sony_acpi_driver = { static int __init sony_acpi_init(void) { - int result; - - sony_acpi_dir = proc_mkdir("sony", acpi_root_dir); - if (!sony_acpi_dir) { - printk(LOG_PFX "unable to create /proc entry\n"); - return -ENODEV; - } - sony_acpi_dir->owner = THIS_MODULE; - - result = acpi_bus_register_driver(&sony_acpi_driver); - if (result < 0) { - remove_proc_entry("sony", acpi_root_dir); - return -ENODEV; - } - return 0; + return acpi_bus_register_driver(&sony_acpi_driver); } static void __exit sony_acpi_exit(void) { acpi_bus_unregister_driver(&sony_acpi_driver); - remove_proc_entry("sony", acpi_root_dir); } module_init(sony_acpi_init); -- 1.4.4.3 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/4] Small update to the Kconfig help to make people believe this driver is useful. 2007-02-07 19:01 ` [PATCH 2/4] Remove /proc/acpi/sony interface and implement platform_device malattia @ 2007-02-07 19:01 ` malattia 2007-02-07 19:01 ` [PATCH 4/4] Group functions and structures to better draw subsytems usage malattia 2007-02-10 1:47 ` [PATCH 2/4] Remove /proc/acpi/sony interface and implement platform_device Alessandro Guido 1 sibling, 1 reply; 10+ messages in thread From: malattia @ 2007-02-07 19:01 UTC (permalink / raw) To: lenb; +Cc: linux-acpi, Mattia Dongili From: Mattia Dongili <malattia@linux.it> Signed-off-by: Mattia Dongili <malattia@linux.it> --- drivers/misc/Kconfig | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 4acd922..926ae11 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -117,7 +117,8 @@ config SONY_LAPTOP It gives access to some extra laptop functionalities. In its current form, the only thing this driver does is letting - the user set or query the screen brightness. + the user set or query the screen brightness and remove/apply + power to some devices. Read <file:Documentation/acpi/sony_acpi.txt> for more information. -- 1.4.4.3 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/4] Group functions and structures to better draw subsytems usage 2007-02-07 19:01 ` [PATCH 3/4] Small update to the Kconfig help to make people believe this driver is useful malattia @ 2007-02-07 19:01 ` malattia 0 siblings, 0 replies; 10+ messages in thread From: malattia @ 2007-02-07 19:01 UTC (permalink / raw) To: lenb; +Cc: linux-acpi, Mattia Dongili From: Mattia Dongili <malattia@linux.it> Signed-off-by: Mattia Dongili <malattia@linux.it> --- drivers/misc/sony-laptop.c | 92 ++++++++++++++++++++++++------------------- 1 files changed, 51 insertions(+), 41 deletions(-) diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c index 1d14969..4a69ce7 100644 --- a/drivers/misc/sony-laptop.c +++ b/drivers/misc/sony-laptop.c @@ -54,16 +54,6 @@ module_param(debug, int, 0); MODULE_PARM_DESC(debug, "set this to 1 (and RTFM) if you want to help " "the development of this driver"); -static int sony_backlight_update_status(struct backlight_device *bd); -static int sony_backlight_get_brightness(struct backlight_device *bd); -static struct backlight_device *sony_backlight_device; -static struct backlight_properties sony_backlight_properties = { - .owner = THIS_MODULE, - .update_status = sony_backlight_update_status, - .get_brightness = sony_backlight_get_brightness, - .max_brightness = SONY_MAX_BRIGHTNESS - 1, -}; - static ssize_t sony_acpi_show(struct device *, struct device_attribute *, char *); static ssize_t sony_acpi_store(struct device *, struct device_attribute *, const char *, size_t); @@ -137,6 +127,9 @@ static struct sony_acpi_value sony_acpi_values[] = { static acpi_handle sony_acpi_handle; static struct acpi_device *sony_acpi_acpi_device = NULL; +/* + * acpi_evaluate_object wrappers + */ static int acpi_callgetfunc(acpi_handle handle, char *name, int *result) { struct acpi_buffer output; @@ -335,25 +328,37 @@ static void sony_snc_pf_remove(void) platform_driver_unregister(&sncpf_driver); } -static int sony_acpi_resume(struct acpi_device *device) +/* + * Backlight device + */ +static int sony_backlight_update_status(struct backlight_device *bd) { - struct sony_acpi_value *item; + return acpi_callsetfunc(sony_acpi_handle, "SBRT", + bd->props->brightness + 1, + NULL); +} - for (item = sony_acpi_values; item->name; item++) { - int ret; +static int sony_backlight_get_brightness(struct backlight_device *bd) +{ + int value; - if (!item->valid) - continue; - ret = acpi_callsetfunc(sony_acpi_handle, *item->acpiset, - item->value, NULL); - if (ret < 0) { - printk("%s: %d\n", __FUNCTION__, ret); - break; - } - } - return 0; + if (acpi_callgetfunc(sony_acpi_handle, "GBRT", &value)) + return 0; + /* brightness levels are 1-based, while backlight ones are 0-based */ + return value - 1; } +static struct backlight_device *sony_backlight_device; +static struct backlight_properties sony_backlight_properties = { + .owner = THIS_MODULE, + .update_status = sony_backlight_update_status, + .get_brightness = sony_backlight_get_brightness, + .max_brightness = SONY_MAX_BRIGHTNESS - 1, +}; + +/* + * ACPI callbacks + */ static void sony_acpi_notify(acpi_handle handle, u32 event, void *data) { if (debug) @@ -376,6 +381,28 @@ static acpi_status sony_walk_callback(acpi_handle handle, u32 level, return AE_OK; } +/* + * ACPI device + */ +static int sony_acpi_resume(struct acpi_device *device) +{ + struct sony_acpi_value *item; + + for (item = sony_acpi_values; item->name; item++) { + int ret; + + if (!item->valid) + continue; + ret = acpi_callsetfunc(sony_acpi_handle, *item->acpiset, + item->value, NULL); + if (ret < 0) { + printk("%s: %d\n", __FUNCTION__, ret); + break; + } + } + return 0; +} + static int sony_acpi_add(struct acpi_device *device) { acpi_status status; @@ -461,23 +488,6 @@ static int sony_acpi_remove(struct acpi_device *device, int type) return 0; } -static int sony_backlight_update_status(struct backlight_device *bd) -{ - return acpi_callsetfunc(sony_acpi_handle, "SBRT", - bd->props->brightness + 1, - NULL); -} - -static int sony_backlight_get_brightness(struct backlight_device *bd) -{ - int value; - - if (acpi_callgetfunc(sony_acpi_handle, "GBRT", &value)) - return 0; - /* brightness levels are 1-based, while backlight ones are 0-based */ - return value - 1; -} - static struct acpi_driver sony_acpi_driver = { .name = ACPI_SNC_DRIVER_NAME, .class = ACPI_SNC_CLASS, -- 1.4.4.3 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 2/4] Remove /proc/acpi/sony interface and implement platform_device. 2007-02-07 19:01 ` [PATCH 2/4] Remove /proc/acpi/sony interface and implement platform_device malattia 2007-02-07 19:01 ` [PATCH 3/4] Small update to the Kconfig help to make people believe this driver is useful malattia @ 2007-02-10 1:47 ` Alessandro Guido 2007-02-10 12:49 ` Mattia Dongili 1 sibling, 1 reply; 10+ messages in thread From: Alessandro Guido @ 2007-02-10 1:47 UTC (permalink / raw) To: malattia; +Cc: lenb, linux-acpi Thanks for doing this! I hope this will be merged soon in mainline :) I'm testing it on my VGN-FS215S and so far I haven't noticed any problem. Just a thing: brightness_default uses values starting from 1. In my opinion, it should be changed to use values starting from 0 to have some consistency or, better, have an entry itself in the backlight interface. What do you think? -Alessandro ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/4] Remove /proc/acpi/sony interface and implement platform_device. 2007-02-10 1:47 ` [PATCH 2/4] Remove /proc/acpi/sony interface and implement platform_device Alessandro Guido @ 2007-02-10 12:49 ` Mattia Dongili 0 siblings, 0 replies; 10+ messages in thread From: Mattia Dongili @ 2007-02-10 12:49 UTC (permalink / raw) To: Alessandro Guido; +Cc: lenb, linux-acpi On Sat, Feb 10, 2007 at 02:47:19AM +0100, Alessandro Guido wrote: > Thanks for doing this! I hope this will be merged soon in mainline :) > I'm testing it on my VGN-FS215S and so far I haven't noticed any > problem. > > Just a thing: > > brightness_default uses values starting from 1. In my opinion, it should > be changed to use values starting from 0 to have some consistency or, > better, have an entry itself in the backlight interface. I don't think the latter is possible, at least not without patching the backlight class framework but I don't know if this has ever been discussed with backlight subsytem maintainers. While I thought about the former suggestion too. It needs some work to keep the generalized sysfs_{show,store} functions but it's definitely worth implementing. Thanks for the feedback :) -- mattia :wq! ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/4] Create sony-laptop 2007-02-07 19:01 ` [PATCH 1/4] Create sony-laptop malattia 2007-02-07 19:01 ` [PATCH 2/4] Remove /proc/acpi/sony interface and implement platform_device malattia @ 2007-02-07 20:50 ` Len Brown 2007-02-07 21:37 ` Mattia Dongili 2007-02-08 9:04 ` Andrew Morton 1 sibling, 2 replies; 10+ messages in thread From: Len Brown @ 2007-02-07 20:50 UTC (permalink / raw) To: malattia, Morton, Andrew; +Cc: linux-acpi Thanks for the follow-up Mattia, I've added this patch series to the acpi-test tree, and added Lindent patch on top of it. I'll double check that it has all the patches from -mm and NAK those when I do, so andrew doesn't get messed up. However, some things need to be addressed before it can go upstream: What happens to sonypi? Where is the patch to update MAINTAINERS for sony-laptop? Documentation/acpi/sony_acpi.txt needs a revision, and a re-name, and the Kconfig help text needs a revision too. Finally, I don't have a Sony laptop so I can't test this. I'd like to see successful test feedback from Andrew, Luming, and other Sony owners before we push it. thanks, -Len ps. I recommend that at some point you globally replace "sony_acpi" in the driver with just "sony". On Wednesday 07 February 2007 14:01, malattia@linux.it wrote: > From: Mattia Dongili <malattia@linux.it> > > > Move drivers/acpi/sony_acpi.c to drivers/misc/sony-laptop.c with all the > necessary configuration. > The SONY_LAPTOP config option substitutes the old ACPI_SONY and is 'default n' > now. > > Signed-off-by: Mattia Dongili <malattia@linux.it> > --- > drivers/acpi/Kconfig | 15 -- > drivers/acpi/Makefile | 1 - > drivers/acpi/sony_acpi.c | 504 -------------------------------------------- > drivers/misc/Kconfig | 14 ++ > drivers/misc/Makefile | 1 + > drivers/misc/sony-laptop.c | 504 ++++++++++++++++++++++++++++++++++++++++++++ > 6 files changed, 519 insertions(+), 520 deletions(-) > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/4] Create sony-laptop 2007-02-07 20:50 ` [PATCH 1/4] Create sony-laptop Len Brown @ 2007-02-07 21:37 ` Mattia Dongili 2007-02-08 9:04 ` Andrew Morton 1 sibling, 0 replies; 10+ messages in thread From: Mattia Dongili @ 2007-02-07 21:37 UTC (permalink / raw) To: Len Brown; +Cc: Morton, Andrew, linux-acpi On Wed, 2007-02-07 at 15:50 -0500, Len Brown wrote: > Thanks for the follow-up Mattia, > > I've added this patch series to the acpi-test tree, > and added Lindent patch on top of it. I'll double check > that it has all the patches from -mm and NAK those > when I do, so andrew doesn't get messed up. Thanks a lot Len! > However, some things need to be addressed > before it can go upstream: > > What happens to sonypi? Currently it's still needed, it deals with a different ACPI device (SPIC instead of SNC). I'm still attempting to undrerstand how it could be merged into sony-laptop. Will try to followup soon with more about that. You can see them in DSDTs here: http://oioio.altervista.org/linux/DSDT.sz72b.dsl http://oioio.altervista.org/linux/DSDT.ux50.dsl > Where is the patch to update MAINTAINERS for sony-laptop? > Documentation/acpi/sony_acpi.txt needs a revision, and a re-name, > and the Kconfig help text needs a revision too. Yup, will send them asap (tomorrow, time to sleep here now). > Finally, I don't have a Sony laptop so I can't test this. > I'd like to see successful test feedback from Andrew, > Luming, and other Sony owners before we push it. Ok, I tested the driver on 2 recent models: SZ72B and UX50. > ps. I recommend that at some point you globally replace "sony_acpi" > in the driver with just "sony". Ok. Thanks again -- mattia :wq ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/4] Create sony-laptop 2007-02-07 20:50 ` [PATCH 1/4] Create sony-laptop Len Brown 2007-02-07 21:37 ` Mattia Dongili @ 2007-02-08 9:04 ` Andrew Morton 1 sibling, 0 replies; 10+ messages in thread From: Andrew Morton @ 2007-02-08 9:04 UTC (permalink / raw) To: Len Brown; +Cc: malattia, linux-acpi On Wed, 7 Feb 2007 15:50:35 -0500 Len Brown <lenb@kernel.org> wrote: > Finally, I don't have a Sony laptop so I can't test this. > I'd like to see successful test feedback from Andrew, > Luming, and other Sony owners before we push it. Seems to work. At least, I can still alter the brightness - I've never worked out how to get that driver to do anything else. The sony-laptop module doesn't get loaded at boot (FC5). Should it? I always get asus_acpi loaded, even on the x86_64 server. I want some of that on the sony ;) ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2007-02-10 12:50 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2007-02-07 19:01 [PATCH 0/4] sony_acpi-0.4: morph into sony-laptop malattia 2007-02-07 19:01 ` [PATCH 1/4] Create sony-laptop malattia 2007-02-07 19:01 ` [PATCH 2/4] Remove /proc/acpi/sony interface and implement platform_device malattia 2007-02-07 19:01 ` [PATCH 3/4] Small update to the Kconfig help to make people believe this driver is useful malattia 2007-02-07 19:01 ` [PATCH 4/4] Group functions and structures to better draw subsytems usage malattia 2007-02-10 1:47 ` [PATCH 2/4] Remove /proc/acpi/sony interface and implement platform_device Alessandro Guido 2007-02-10 12:49 ` Mattia Dongili 2007-02-07 20:50 ` [PATCH 1/4] Create sony-laptop Len Brown 2007-02-07 21:37 ` Mattia Dongili 2007-02-08 9:04 ` Andrew Morton
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.