sony_acpi: getting in shape for prime time
Subsystems (2)
cover sony_acpi: getting in shape for prime time
Hello Len,
I'm sending this first batch of patches for review:
- 1 to 7 are currently present in -mm
- 8 to 10 are my local changes to have sony_acpi do something more interesting in recent vaios
- 11 initializes the real brightness value in the backlight props (should this go in the backlight class itself?).
I'll start turning /proc to platform_device in the next days.
So, let's go! Comments are very welcome. :)
Signature · 2 lines
mattia :wq
PATCH 1/11 SNC device support for Sony Vaios
From: Stelian Pop <[email protected]>
From: Bjorn Helgaas <[email protected]>
Even though the devices claimed by sony_acpi.c can not be hot-plugged, the driver registration infrastructure allows the .add() and .remove() methods to be called at any time while the driver is registered. So remove __init and __exit from them.
DESC
acpi/sony: Add FN hotkey support
EDESC
From: Matthew Garrett <[email protected]>
in -mm only
[UBUNTU:acpi/sony] Add FN hotkey support
Source URL of Patch:
http://www.kernel.org/git/?p=linux/kernel/git/bcollins/ubuntu-dapper.git;a=commitdiff;h=7a9b49cba4919e8506604629db03add8e0b85767
--- Documentation/acpi/sony_acpi.txt | 87 +++++++++ drivers/acpi/Kconfig | 14 ++ drivers/acpi/Makefile | 1 + drivers/acpi/sony_acpi.c | 397 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 499 insertions(+), 0 deletions(-)
Documentation/acpi/sony_acpi.txt new file +87 -0
@@ -0,0 +1,87 @@ +ACPI Sony Notebook Control Driver (SNC) Readme +---------------------------------------------- + Copyright (C) 2004- 2005 Stelian Pop <[email protected]> + +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, this driver is mainly useful for controlling the +screen brightness, but it may do more in the future. + +You should probably start by trying the sonypi driver, and try +sony_acpi only if sonypi doesn't work for you. + +Usage: +------ + +Loading the sony_acpi module will create a /proc/acpi/sony/ +directory populated with a couple of files. + +You then read/write integer values from/to those files by using +standard UNIX tools. + +The files are: + brightness current screen brightness + brightness_default screen brightness which will be set + when the laptop will be rebooted + cdpower power on/off the internal CD drive + +Note that some files may be missing if they are not supported +by your particular laptop model. + +Example usage: + # echo "1" > /proc/acpi/sony/brightness +sets the lowest screen brightness, + # echo "8" > /proc/acpi/sony/brightness +sets the highest screen brightness, + # cat /proc/acpi/sony/brightness +retrieves the current screen brightness. + +Development: +------------ + +If you want to help with the development of this driver (and +you are not afraid of any side effects doing strange things with +your ACPI BIOS could have on your laptop), load the driver and +pass the option 'debug=1'. + +REPEAT: DON'T DO THIS IF YOU DON'T LIKE RISKY BUSINESS. + +In your kernel logs you will find the list of all ACPI methods +the SNC device has on your laptop. You can see the GBRT/SBRT methods +used to get/set the brightness, but there are others. + +I HAVE NO IDEA WHAT THOSE METHODS DO. + +The sony_acpi driver creates, for some of those methods (the most +current ones found on several Vaio models), an entry under +/proc/acpi/sony/, just like the 'brightness' one. You can create +other entries corresponding to your own laptop methods by further +editing the source (see the 'sony_acpi_values' table, and add a new +structure to this table with your get/set method names). + +Your mission, should you accept it, is to try finding out what +those entries are for, by reading/writing random values from/to those +files and find out what is the impact on your laptop. + +Should you find anything interesting, please report it back to me, +I will not disavow all knowledge of your actions :) + +Bugs/Limitations: +----------------- + +* This driver is not based on official documentation from Sony + (because there is none), so there is no guarantee this driver + will work at all, or do the right thing. Although this hasn't + happened to me, this driver could do very bad things to your + laptop, including permanent damage. + +* The sony_acpi and sonypi drivers do not interact at all. In the + future, sonypi could use sony_acpi to do (part of) its business. + +* spicctrl, which is the userspace tool used to communicate with the + sonypi driver (through /dev/sonypi) does not try to use the + sony_acpi driver. In the future, spicctrl could try sonypi first, + and if it isn't present, try sony_acpi instead. +
drivers/acpi/Kconfig +14 -0
@@ -261,6 +261,20 @@ 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 + 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
drivers/acpi/Makefile +1 -0
@@ -54,6 +54,7 @@ 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
drivers/acpi/sony_acpi.c new file +397 -0
397 lines not on this page · raw message
Signature · 1 line
1.4.4.2
PATCH 2/11 Avoid dimness on resume.
From: Andrew Morton <[email protected]>
Doesn't work.
--- drivers/acpi/sony_acpi.c | 49 +++++++++++++++++++++++++++++++-------------- 1 files changed, 34 insertions(+), 15 deletions(-)
drivers/acpi/sony_acpi.c +34 -15
@@ -46,19 +46,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_acpi_add (struct acpi_device *device); -static int sony_acpi_remove (struct acpi_device *device,int type); - -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, - }, -}; -static acpi_handle sony_acpi_handle;static struct proc_dir_entry *sony_acpi_dir;
@@ -69,6 +56,8 @@ static struct sony_acpi_value {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[] = { {
@@ -239,10 +228,30 @@ static int sony_acpi_write(struct file *file, const char __user *buffer,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,int state) +{ +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) {printk (LOG_PFX "sony_acpi_notify\n" );
@@ -344,7 +353,6 @@ outwalk:return result; } -static int sony_acpi_remove (struct acpi_device *device,int type) {acpi_status status;
@@ -367,6 +375,17 @@ static int sony_acpi_remove(struct acpi_device *device, int type)return 0 ; } +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;
Signature · 1 line
1.4.4.2
PATCH 3/11 Fix sony_acpi_resume call
From: Andrew Morton <[email protected]>
--- drivers/acpi/sony_acpi.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/acpi/sony_acpi.c +1 -1
@@ -233,7 +233,7 @@ static int sony_acpi_write(struct file *file, const char __user *buffer,return count; } -static int sony_acpi_resume (struct acpi_device *device,int state) +static int sony_acpi_resume (struct acpi_device *device) {struct sony_acpi_value *item;
Signature · 1 line
1.4.4.2
PATCH 4/11 Add backlight support to the sony_acpi
From: Alessandro Guido <[email protected]>
Make the sony_acpi use the backlight subsystem to adjust brightness value instead of using the /proc/sony/brightness file. (Other settings will still have a /proc/sony/... entry)
--- drivers/acpi/Kconfig | 1 + drivers/acpi/sony_acpi.c | 59 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 48 insertions(+), 12 deletions(-)
drivers/acpi/Kconfig +1 -0
@@ -264,6 +264,7 @@ config ACPI_TOSHIBA 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
drivers/acpi/sony_acpi.c +47 -12
112 lines not on this page · raw message
Signature · 1 line
1.4.4.2
PATCH 5/11 Add backlight support to the sony_acpi v2
From: Alessandro Guido <[email protected]>
Enable the sony_acpi driver to use the backlight subsysyem for adjusting the monitor brightness. Old way of changing the brightness will be still available for compatibility with existing tools.
--- drivers/acpi/sony_acpi.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-)
drivers/acpi/sony_acpi.c +8 -0
@@ -77,6 +77,14 @@ static struct sony_acpi_value {int debug;/* active only in debug mode ? */ } sony_acpi_values[] = { { + .name = "brightness", + .acpiget = "GBRT", + .acpiset = "SBRT", + .min = 1, + .max = SONY_MAX_BRIGHTNESS, + .debug = 0, + }, + { .name = "brightness_default", .acpiget = "GPBR", .acpiset = "SPBR",
Signature · 1 line
1.4.4.2
PATCH 6/11 Video sysfs support take 2
From: Andrew Morton <[email protected]>
add dev argument for backlight_device_register
--- drivers/acpi/sony_acpi.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/acpi/sony_acpi.c +1 -1
@@ -322,7 +322,7 @@ static int sony_acpi_add(struct acpi_device *device)if (ACPI_SUCCESS (acpi_get_handle (sony_acpi_handle,"GBRT" , &handle))) { sony_backlight_device =backlight_device_register ("sony" ,NULL , - &sony_backlight_properties); +NULL , &sony_backlight_properties);if (IS_ERR (sony_backlight_device)) {printk (LOG_PFX "unable to register backlight device\n" ); }
Signature · 1 line
1.4.4.2
PATCH 7/11 Add acpi_bus_generate event
From: Stelian Pop <[email protected]>
Added acpi_bus_generate event for forwarding Fn-keys pressed to acpi subsystem, and made correspondent necessary changes for this to work.
--- drivers/acpi/sony_acpi.c | 53 ++++++++++++++++++++++++--------------------- 1 files changed, 28 insertions(+), 25 deletions(-)
drivers/acpi/sony_acpi.c +28 -25
@@ -54,6 +54,7 @@ MODULE_PARM_DESC(debug, "set this to 1 (and RTFM) if you want to help "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);
@@ -270,7 +271,9 @@ static int sony_acpi_resume(struct acpi_device *device)static void sony_acpi_notify (acpi_handle handle,u32 event,void *data) { -printk (LOG_PFX "sony_acpi_notify\n" ); +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,
@@ -295,6 +298,8 @@ static int sony_acpi_add(struct acpi_device *device)acpi_handle handle;struct sony_acpi_value *item; + sony_acpi_acpi_device = device; + sony_acpi_handle = device->handle;acpi_driver_data (device) =NULL ;
@@ -308,16 +313,16 @@ static int sony_acpi_add(struct acpi_device *device) 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; - } + 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))) {
@@ -342,7 +347,7 @@ static int sony_acpi_add(struct acpi_device *device) item->acpiset, &handle)))continue ; - item->proc =create_proc_entry (item->name,0600 , + item->proc =create_proc_entry (item->name,0666 ,acpi_device_dir (device));if (!item->proc) {printk (LOG_PFX "unable to create proc entry\n" );
@@ -361,13 +366,11 @@ static int sony_acpi_add(struct acpi_device *device)return 0 ; outproc: -if (debug) { - 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" ); - } + 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" ); outnotify:for (item = sony_acpi_values; item->name; ++item)if (item->proc)
@@ -384,13 +387,13 @@ static int sony_acpi_remove(struct acpi_device *device, int type)if (sony_backlight_device)backlight_device_unregister (sony_backlight_device); -if (debug) { - 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" ); - } + 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)
Signature · 1 line
1.4.4.2
PATCH 8/11 Allow easier debugging for the unknown SNC methods.
From: Mattia Dongili <[email protected]>
Allow the existence of a setter method without a getter and viceversa, additionaly set /proc file permissions reflecting it.
Fix also the error exit path.
--- drivers/acpi/sony_acpi.c | 30 +++++++++++++++++++++--------- 1 files changed, 21 insertions(+), 9 deletions(-)
drivers/acpi/sony_acpi.c +21 -9
@@ -296,6 +296,7 @@ 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;
@@ -334,20 +335,31 @@ static int sony_acpi_add(struct acpi_device *device) }for (item = sony_acpi_values; item->name; ++item) { + proc_file_mode =0 ; +if (!debug && item->debug)continue ;if (item->acpiget && -ACPI_FAILURE (acpi_get_handle (sony_acpi_handle, +ACPI_SUCCESS (acpi_get_handle (sony_acpi_handle, item->acpiget, &handle))) -continue ; + proc_file_mode =S_IRUSR ; +else +printk (LOG_PFX "unable to get ACPI handle for %s (get)\n" , + item->name);if (item->acpiset && -ACPI_FAILURE (acpi_get_handle (sony_acpi_handle, +ACPI_SUCCESS (acpi_get_handle (sony_acpi_handle, item->acpiset, &handle))) -continue ; + proc_file_mode |=S_IWUSR ; +else +printk (LOG_PFX "unable to get ACPI handle for %s (set)\n" , + item->name); + +if (proc_file_mode ==0 ) +continue ; - item->proc =create_proc_entry (item->name,0666 , + 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" );
@@ -366,15 +378,15 @@ static int sony_acpi_add(struct acpi_device *device)return 0 ; outproc: +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" ); -outnotify: -for (item = sony_acpi_values; item->name; ++item) -if (item->proc) -remove_proc_entry (item->name,acpi_device_dir (device)); outwalk:return result; }
Signature · 1 line
1.4.4.2
PATCH 9/11 Add lanpower and audiopower controls
From: Mattia Dongili <[email protected]>
audiopower works well on my SZ72B so it's not marked has "debug" while lanpower has at least one report of not resuming power happily so morked as "debug"
--- drivers/acpi/sony_acpi.c | 20 ++++++++++++++++++-- 1 files changed, 18 insertions(+), 2 deletions(-)
drivers/acpi/sony_acpi.c +18 -2
@@ -102,11 +102,27 @@ static struct sony_acpi_value { .name = "cdpower", .acpiget = "GCDP", .acpiset = "SCDP", - .min = -1, - .max = -1, + .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,
Signature · 1 line
1.4.4.2
PATCH 10/11 Allow multiple sony_acpi_values for the same .name
From: Mattia Dongili <[email protected]>
The acpi handles are kept _only_ if both the requested .acpiget and .acpiset are available in the DSDT.
Currently only the SCDP/CDPW dualism is known.
--- drivers/acpi/sony_acpi.c | 44 +++++++++++++++++++++++++------------------- 1 files changed, 25 insertions(+), 19 deletions(-)
drivers/acpi/sony_acpi.c +25 -19
@@ -68,7 +68,7 @@ static struct backlight_properties sony_backlight_properties = { static struct sony_acpi_value { char *name; /* name of the entry */ - struct proc_dir_entry *proc; /* /proc 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 */
@@ -78,6 +78,7 @@ static struct sony_acpi_value {int debug;/* active only in debug mode ? */ } sony_acpi_values[] = { { +/* for backward compatibility only */ .name = "brightness", .acpiget = "GBRT", .acpiset = "SBRT",
@@ -107,6 +108,14 @@ static struct sony_acpi_value { .debug = 0, }, { + .name = "cdpower", + .acpiget = "GCDP", + .acpiset = "CDPW", + .min = 0, + .max = 1, + .debug = 0, + }, + { .name = "audiopower", .acpiget = "GAZP", .acpiset = "AZPW",
@@ -356,27 +365,24 @@ static int sony_acpi_add(struct acpi_device *device)if (!debug && item->debug)continue ; -if (item->acpiget && -ACPI_SUCCESS (acpi_get_handle (sony_acpi_handle, - item->acpiget, &handle))) - proc_file_mode =S_IRUSR ; -else -printk (LOG_PFX "unable to get ACPI handle for %s (get)\n" , - item->name); - -if (item->acpiset && -ACPI_SUCCESS (acpi_get_handle (sony_acpi_handle, - item->acpiset, &handle))) - proc_file_mode |=S_IWUSR ; -else -printk (LOG_PFX "unable to get ACPI handle for %s (set)\n" , - item->name); +if (item->acpiget) { +if (ACPI_FAILURE (acpi_get_handle (sony_acpi_handle, + item->acpiget, &handle))) +continue ; -if (proc_file_mode ==0 ) -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)); +acpi_device_dir (device));if (!item->proc) {printk (LOG_PFX "unable to create proc entry\n" ); result = -EIO ;
Signature · 1 line
1.4.4.2
PATCH 11/11 initialize the brighness value at device registration
From: Mattia Dongili <[email protected]>
--- drivers/acpi/sony_acpi.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
drivers/acpi/sony_acpi.c +2 -0
@@ -357,6 +357,8 @@ static int sony_acpi_add(struct acpi_device *device)if (IS_ERR (sony_backlight_device)) {printk (LOG_PFX "unable to register backlight device\n" ); } + sony_backlight_properties.brightness = +sony_backlight_get_brightness (sony_backlight_device); }for (item = sony_acpi_values; item->name; ++item) {
Signature · 1 line
1.4.4.2
Re: [PATCH 11/11] initialize the brighness value at device registration
Quoted 12 lines · On Sun, Jan 07, 2007 at 06:54:43PM +0100, [email protected] wrote:
From: Mattia Dongili <[email protected]>
Signed-off-by Mattia Dongili <[email protected]>--- drivers/acpi/sony_acpi.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)drivers/acpi/sony_acpi.c +0
-0
drivers/acpi/sony_acpi.c static int sony_acpi_add(struct acpi_device *device) · line 361
Quoted 5 lines
drivers/acpi/sony_acpi.c +2
-0@@ -357,6 +357,8 @@ static int sony_acpi_add(struct acpi_device *device)if (IS_ERR (sony_backlight_device)) {printk (LOG_PFX "unable to register backlight device\n" ); } + sony_backlight_properties.brightness = +sony_backlight_get_brightness (sony_backlight_device);
Ok, this one is at wrong and incomplete (the error exit path is missing the backlight device unregistration).
Will resend a correct patch later.
Signature · 2 lines
mattia :wq!