Remove ACPI references from variable and function names.
Subsystems (3)
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 1/9 Remove ACPI references from variable and function names.
--- drivers/misc/sony-laptop.c | 178 ++++++++++++++++++++++---------------------- 1 files changed, 89 insertions(+), 89 deletions(-)
drivers/misc/sony-laptop.c +93 -93
@@ -35,9 +35,9 @@#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.4" +#define SONY_NC_CLASS "sony" +#define SONY_NC_HID "SNY5001" +#define SONY_NC_DRIVER_NAME "ACPI Sony Notebook Control Driver v0.4"/* the device uses 1-based values, while the backlight subsystem uses 0-based values */
@@ -46,7 +46,7 @@#define LOG_PFX KERN_WARNING "sony-laptop: "MODULE_AUTHOR ("Stelian Pop, Mattia Dongili" ); -MODULE_DESCRIPTION (ACPI_SNC_DRIVER_NAME ); +MODULE_DESCRIPTION (SONY_NC_DRIVER_NAME );MODULE_LICENSE ("GPL" );static int debug;
@@ -54,9 +54,9 @@ 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 ssize_t sony_acpi_show (struct device *,struct device_attribute *, +static ssize_t sony_nc_sysfs_show (struct device *,struct device_attribute *,char *); -static ssize_t sony_acpi_store (struct device *,struct device_attribute *, +static ssize_t sony_nc_sysfs_store (struct device *,struct device_attribute *,const char *,size_t );static int boolean_validate (const int ,const int );static int brightness_default_validate (const int ,const int );
@@ -64,7 +64,7 @@ static int brightness_default_validate(c#define SNC_VALIDATE_IN 0#define SNC_VALIDATE_OUT 1 -struct sony_acpi_value { +struct sony_nc_value {char *name;/* name of the entry */ char **acpiget;/* names of the ACPI get function */ char **acpiset;/* names of the ACPI set function */
@@ -75,65 +75,65 @@ struct sony_acpi_value {struct device_attribute devattr;/* sysfs atribute */ }; -#define HANDLE_NAMES(_name, _values...) \ +#define SNC_HANDLE_NAMES(_name, _values...) \ static char *snc_##_name[] = { _values, NULL } -#define SONY_ACPI_VALUE (_name, _getters, _setters, _validate, _debug) \ +#define SNC_HANDLE (_name, _getters, _setters, _validate, _debug) \ { \ .name = __stringify(_name), \ .acpiget = _getters, \ .acpiset = _setters, \ .validate = _validate, \ .debug = _debug, \ - .devattr = __ATTR(_name, 0, sony_acpi_show, sony_acpi_store), \ + .devattr = __ATTR(_name, 0, sony_nc_sysfs_show, sony_nc_sysfs_store), \ } -#define SONY_ACPI_VALUE_NULL { .name = NULL } +#define SNC_HANDLE_NULL { .name = NULL } -HANDLE_NAMES (fnkey_get,"GHKE" ); +SNC_HANDLE_NAMES (fnkey_get,"GHKE" ); -HANDLE_NAMES (brightness_def_get,"GPBR" ); -HANDLE_NAMES (brightness_def_set,"SPBR" ); +SNC_HANDLE_NAMES (brightness_def_get,"GPBR" ); +SNC_HANDLE_NAMES (brightness_def_set,"SPBR" ); -HANDLE_NAMES (cdpower_get,"GCDP" ); -HANDLE_NAMES (cdpower_set,"SCDP" ,"CDPW" ); +SNC_HANDLE_NAMES (cdpower_get,"GCDP" ); +SNC_HANDLE_NAMES (cdpower_set,"SCDP" ,"CDPW" ); -HANDLE_NAMES (audiopower_get,"GAZP" ); -HANDLE_NAMES (audiopower_set,"AZPW" ); +SNC_HANDLE_NAMES (audiopower_get,"GAZP" ); +SNC_HANDLE_NAMES (audiopower_set,"AZPW" ); -HANDLE_NAMES (lanpower_get,"GLNP" ); -HANDLE_NAMES (lanpower_set,"LNPW" ); +SNC_HANDLE_NAMES (lanpower_get,"GLNP" ); +SNC_HANDLE_NAMES (lanpower_set,"LNPW" ); -HANDLE_NAMES (PID_get,"GPID" ); +SNC_HANDLE_NAMES (PID_get,"GPID" ); -HANDLE_NAMES (CTR_get,"GCTR" ); -HANDLE_NAMES (CTR_set,"SCTR" ); +SNC_HANDLE_NAMES (CTR_get,"GCTR" ); +SNC_HANDLE_NAMES (CTR_set,"SCTR" ); -HANDLE_NAMES (PCR_get,"GPCR" ); -HANDLE_NAMES (PCR_set,"SPCR" ); +SNC_HANDLE_NAMES (PCR_get,"GPCR" ); +SNC_HANDLE_NAMES (PCR_set,"SPCR" ); -HANDLE_NAMES (CMI_get,"GCMI" ); -HANDLE_NAMES (CMI_set,"SCMI" ); +SNC_HANDLE_NAMES (CMI_get,"GCMI" ); +SNC_HANDLE_NAMES (CMI_set,"SCMI" ); -static struct sony_acpi_value sony_acpi_values[] = { -SONY_ACPI_VALUE (brightness_default, snc_brightness_def_get, +static struct sony_nc_value sony_nc_values[] = { +SNC_HANDLE (brightness_default, snc_brightness_def_get, snc_brightness_def_set, brightness_default_validate,0 ), -SONY_ACPI_VALUE (fnkey, snc_fnkey_get,NULL ,NULL ,0 ), -SONY_ACPI_VALUE (cdpower, snc_cdpower_get, snc_cdpower_set, boolean_validate,0 ), -SONY_ACPI_VALUE (audiopower, snc_audiopower_get, snc_audiopower_set, +SNC_HANDLE (fnkey, snc_fnkey_get,NULL ,NULL ,0 ), +SNC_HANDLE (cdpower, snc_cdpower_get, snc_cdpower_set, boolean_validate,0 ), +SNC_HANDLE (audiopower, snc_audiopower_get, snc_audiopower_set, boolean_validate,0 ), -SONY_ACPI_VALUE (lanpower, snc_lanpower_get, snc_lanpower_set, +SNC_HANDLE (lanpower, snc_lanpower_get, snc_lanpower_set, boolean_validate,1 ),/* unknown methods */ -SONY_ACPI_VALUE (PID , snc_PID_get,NULL ,NULL ,1 ), -SONY_ACPI_VALUE (CTR , snc_CTR_get, snc_CTR_set,NULL ,1 ), -SONY_ACPI_VALUE (PCR , snc_PCR_get, snc_PCR_set,NULL ,1 ), -SONY_ACPI_VALUE (CMI , snc_CMI_get, snc_CMI_set,NULL ,1 ), -SONY_ACPI_VALUE_NULL +SNC_HANDLE (PID , snc_PID_get,NULL ,NULL ,1 ), +SNC_HANDLE (CTR , snc_CTR_get, snc_CTR_set,NULL ,1 ), +SNC_HANDLE (PCR , snc_PCR_get, snc_PCR_set,NULL ,1 ), +SNC_HANDLE (CMI , snc_CMI_get, snc_CMI_set,NULL ,1 ), +SNC_HANDLE_NULL }; -static acpi_handle sony_acpi_handle; -static struct acpi_device *sony_acpi_acpi_device =NULL ; +static acpi_handle sony_nc_acpi_handle; +static struct acpi_device *sony_nc_acpi_device =NULL ;/* * acpi_evaluate_object wrappers
@@ -194,7 +194,7 @@ static int acpi_callsetfunc(acpi_handle }/* -* sony_acpi_values input/output validate functions +* sony_nc_values input/output validate functions */ /* brightness_default_validate:
@@ -229,19 +229,19 @@ static int boolean_validate(const int di }/* -* Sysfs show/store common to all sony_acpi_values +* Sysfs show/store common to all sony_nc_values */ -static ssize_t sony_acpi_show (struct device *dev,struct device_attribute *attr, +static ssize_t sony_nc_sysfs_show (struct device *dev,struct device_attribute *attr,char *buffer) {int value; -struct sony_acpi_value *item = - container_of(attr, struct sony_acpi_value, devattr); +struct sony_nc_value *item = + container_of(attr, struct sony_nc_value, devattr);if (!*item->acpiget)return -EIO ; -if (acpi_callgetfunc (sony_acpi_handle, *item->acpiget, &value) <0 ) +if (acpi_callgetfunc (sony_nc_acpi_handle, *item->acpiget, &value) <0 )return -EIO ;if (item->validate)
@@ -250,13 +250,13 @@ static ssize_t sony_acpi_show(struct devreturn snprintf (buffer,PAGE_SIZE ,"%d\n" , value); } -static ssize_t sony_acpi_store (struct device *dev, +static ssize_t sony_nc_sysfs_store (struct device *dev,struct device_attribute *attr,const char *buffer,size_t count) {int value; -struct sony_acpi_value *item = - container_of(attr, struct sony_acpi_value, devattr); +struct sony_nc_value *item = + container_of(attr, struct sony_nc_value, devattr);if (!item->acpiset)return -EIO ;
@@ -272,7 +272,7 @@ static ssize_t sony_acpi_store(struct deif (value <0 )return value; -if (acpi_callsetfunc (sony_acpi_handle, *item->acpiset, value,NULL ) <0 ) +if (acpi_callsetfunc (sony_nc_acpi_handle, *item->acpiset, value,NULL ) <0 )return -EIO ; item->value = value; item->valid =1 ;
@@ -290,10 +290,10 @@ static struct platform_driver sncpf_driv };static struct platform_device *sncpf_device; -static int sony_snc_pf_add (void ) +static int sony_nc_pf_add (void ) {acpi_handle handle; -struct sony_acpi_value *item; +struct sony_nc_value *item;int ret =0 ; ret =platform_driver_register (&sncpf_driver);
@@ -310,14 +310,14 @@ static int sony_snc_pf_add(void)if (ret) goto out_platform_alloced; -for (item = sony_acpi_values; item->name; ++item) { +for (item = sony_nc_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, +if (ACPI_SUCCESS (acpi_get_handle (sony_nc_acpi_handle, *item->acpiget, &handle))) {if (debug)
@@ -330,7 +330,7 @@ static int sony_snc_pf_add(void)/* 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, +if (ACPI_SUCCESS (acpi_get_handle (sony_nc_acpi_handle, *item->acpiset, &handle))) {if (debug)
@@ -353,7 +353,7 @@ static int sony_snc_pf_add(void)return 0 ; out_sysfs: -for (item = sony_acpi_values; item->name; ++item) { +for (item = sony_nc_values; item->name; ++item) {device_remove_file (&sncpf_device->dev, &item->devattr); }platform_device_del (sncpf_device);
@@ -365,11 +365,11 @@ static int sony_snc_pf_add(void)return ret; } -static void sony_snc_pf_remove (void ) +static void sony_nc_pf_remove (void ) { -struct sony_acpi_value *item; +struct sony_nc_value *item; -for (item = sony_acpi_values; item->name; ++item) { +for (item = sony_nc_values; item->name; ++item) {device_remove_file (&sncpf_device->dev, &item->devattr); }
@@ -383,7 +383,7 @@ static void sony_snc_pf_remove(void)*/ static int sony_backlight_update_status (struct backlight_device *bd) { -return acpi_callsetfunc (sony_acpi_handle,"SBRT" , +return acpi_callsetfunc (sony_nc_acpi_handle,"SBRT" , bd->props.brightness +1 ,NULL ); }
@@ -391,7 +391,7 @@ static int sony_backlight_get_brightness {int value; -if (acpi_callgetfunc (sony_acpi_handle,"GBRT" , &value)) +if (acpi_callgetfunc (sony_nc_acpi_handle,"GBRT" , &value))return 0 ;/* brightness levels are 1-based, while backlight ones are 0-based */ return value -1 ;
@@ -410,7 +410,7 @@ static void sony_acpi_notify(acpi_handle {if (debug)printk (LOG_PFX "sony_acpi_notify, event: %d\n" , event); -acpi_bus_generate_event (sony_acpi_acpi_device,1 , event); +acpi_bus_generate_event (sony_nc_acpi_device,1 , event); } static acpi_status sony_walk_callback(acpi_handle handle, u32 level,
@@ -431,16 +431,16 @@ static acpi_status sony_walk_callback(ac/* * ACPI device */ -static int sony_acpi_resume (struct acpi_device *device) +static int sony_nc_resume (struct acpi_device *device) { -struct sony_acpi_value *item; +struct sony_nc_value *item; -for (item = sony_acpi_values; item->name; item++) { +for (item = sony_nc_values; item->name; item++) {int ret;if (!item->valid)continue ; - ret =acpi_callsetfunc (sony_acpi_handle, *item->acpiset, + ret =acpi_callsetfunc (sony_nc_acpi_handle, *item->acpiset, item->value,NULL );if (ret <0 ) {printk ("%s: %d\n" , __FUNCTION__, ret);
@@ -450,18 +450,18 @@ static int sony_acpi_resume(struct acpi_return 0 ; } -static int sony_acpi_add (struct acpi_device *device) +static int sony_nc_add (struct acpi_device *device) {acpi_status status;int result =0 ;acpi_handle handle; - sony_acpi_acpi_device = device; + sony_nc_acpi_device = device; - sony_acpi_handle = device->handle; + sony_nc_acpi_handle = device->handle;if (debug) { - status =acpi_walk_namespace (ACPI_TYPE_METHOD , sony_acpi_handle, + status =acpi_walk_namespace (ACPI_TYPE_METHOD , sony_nc_acpi_handle,1 , sony_walk_callback,NULL ,NULL );if (ACPI_FAILURE (status)) {printk (LOG_PFX "unable to walk acpi resources\n" );
@@ -470,7 +470,7 @@ static int sony_acpi_add(struct acpi_dev } } - status =acpi_install_notify_handler (sony_acpi_handle, + status =acpi_install_notify_handler (sony_nc_acpi_handle,ACPI_DEVICE_NOTIFY , sony_acpi_notify,NULL );if (ACPI_FAILURE (status)) {
@@ -479,7 +479,7 @@ static int sony_acpi_add(struct acpi_dev goto outwalk; } -if (ACPI_SUCCESS (acpi_get_handle (sony_acpi_handle,"GBRT" , &handle))) { +if (ACPI_SUCCESS (acpi_get_handle (sony_nc_acpi_handle,"GBRT" , &handle))) { sony_backlight_device =backlight_device_register ("sony" ,NULL ,NULL , &sony_backlight_ops);
@@ -497,10 +497,10 @@ static int sony_acpi_add(struct acpi_dev } -if (sony_snc_pf_add ()) +if (sony_nc_pf_add ()) goto outbacklight; - printk(KERN_INFO ACPI_SNC_DRIVER_NAME " successfully installed\n"); + printk(KERN_INFO SONY_NC_DRIVER_NAME " successfully installed\n");return 0 ;
@@ -508,7 +508,7 @@ static int sony_acpi_add(struct acpi_devif (sony_backlight_device)backlight_device_unregister (sony_backlight_device); - status =acpi_remove_notify_handler (sony_acpi_handle, + status =acpi_remove_notify_handler (sony_nc_acpi_handle,ACPI_DEVICE_NOTIFY , sony_acpi_notify);if (ACPI_FAILURE (status))
@@ -517,48 +517,48 @@ static int sony_acpi_add(struct acpi_devreturn result; } -static int sony_acpi_remove (struct acpi_device *device,int type) +static int sony_nc_remove (struct acpi_device *device,int type) {acpi_status status;if (sony_backlight_device)backlight_device_unregister (sony_backlight_device); - sony_acpi_acpi_device =NULL ; + sony_nc_acpi_device =NULL ; - status =acpi_remove_notify_handler (sony_acpi_handle, + status =acpi_remove_notify_handler (sony_nc_acpi_handle,ACPI_DEVICE_NOTIFY , sony_acpi_notify);if (ACPI_FAILURE (status))printk (LOG_PFX "unable to remove notify handler\n" ); -sony_snc_pf_remove (); +sony_nc_pf_remove (); - printk(KERN_INFO ACPI_SNC_DRIVER_NAME " successfully removed\n"); + printk(KERN_INFO SONY_NC_DRIVER_NAME " successfully removed\n");return 0 ; } -static struct acpi_driver sony_acpi_driver = { - .name =ACPI_SNC_DRIVER_NAME , - .class =ACPI_SNC_CLASS , - .ids =ACPI_SNC_HID , +static struct acpi_driver sony_nc_driver = { + .name =SONY_NC_DRIVER_NAME , + .class =SONY_NC_CLASS , + .ids =SONY_NC_HID , .ops = { - .add = sony_acpi_add, - .remove = sony_acpi_remove, - .resume = sony_acpi_resume, + .add = sony_nc_add, + .remove = sony_nc_remove, + .resume = sony_nc_resume, }, }; -static int __init sony_acpi_init (void ) +static int __init sony_laptop_init (void ) { -return acpi_bus_register_driver (&sony_acpi_driver); +return acpi_bus_register_driver (&sony_nc_driver); } -static void __exit sony_acpi_exit(void) +static void __exit sony_laptop_exit(void) { -acpi_bus_unregister_driver (&sony_acpi_driver); +acpi_bus_unregister_driver (&sony_nc_driver); } -module_init (sony_acpi_init); -module_exit (sony_acpi_exit); +module_init (sony_laptop_init); +module_exit (sony_laptop_exit);
--
Signature · 2 lines
mattia :wq!
PATCH 2/9 Prepare the platform driver for multiple users.
In reply to a message not in the archiveBoth the SNC and SPIC device drivers will create attributes and thus there's the need to have an internal usage count to avoid re-registering or de-registering at the wrong time.
--- drivers/misc/sony-laptop.c | 212 ++++++++++++++++++++++++++++++---------------------------- 1 file changed, 112 insertions(+), 100 deletions(-)
drivers/misc/sony-laptop.c +112 -100
@@ -54,6 +54,64 @@ 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" ); +/*********** Platform Device ***********/ + +static atomic_t sony_pf_users =ATOMIC_INIT (0 ); +static struct platform_driver sony_pf_driver = { + .driver = { + .name ="sony-laptop" , + .owner =THIS_MODULE , + } +}; +static struct platform_device *sony_pf_device; + +static int sony_pf_add (void ) +{ +int ret =0 ; + +/* don't run again if already initialized */ +if (atomic_add_return (1 , &sony_pf_users) >1 ) +return 0 ; + + ret =platform_driver_register (&sony_pf_driver); +if (ret) + goto out; + + sony_pf_device =platform_device_alloc ("sony-laptop" ,-1 ); +if (!sony_pf_device) { + ret = -ENOMEM ; + goto out_platform_registered; + } + + ret =platform_device_add (sony_pf_device); +if (ret) + goto out_platform_alloced; + +return 0 ; + + out_platform_alloced: +platform_device_put (sony_pf_device); + sony_pf_device =NULL ; + out_platform_registered: +platform_driver_unregister (&sony_pf_driver); + out: +atomic_dec (&sony_pf_users); +return ret; +} + +static void sony_pf_remove (void ) +{ +/* deregister only after the last user has gone */ +if (!atomic_dec_and_test (&sony_pf_users)) +return ; + +platform_device_del (sony_pf_device); +platform_device_put (sony_pf_device); +platform_driver_unregister (&sony_pf_driver); +} + +/*********** SNC (SNY5001) Device ***********/ +static ssize_t sony_nc_sysfs_show (struct device *,struct device_attribute *,char *); static ssize_t sony_nc_sysfs_store(struct device *, struct device_attribute *,
@@ -279,104 +337,6 @@ static ssize_t sony_nc_sysfs_store(strucreturn 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_nc_pf_add (void ) -{ -acpi_handle handle; -struct sony_nc_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_nc_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_nc_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_nc_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_nc_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_nc_pf_remove (void ) -{ -struct sony_nc_value *item; - -for (item = sony_nc_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); -}/* * Backlight device
@@ -455,6 +415,7 @@ static int sony_nc_add(struct acpi_devicacpi_status status;int result =0 ;acpi_handle handle; +struct sony_nc_value *item; sony_nc_acpi_device = device;
@@ -497,13 +458,59 @@ static int sony_nc_add(struct acpi_devic } -if (sony_nc_pf_add ()) +if (sony_pf_add ()) goto outbacklight; +/* create sony_pf sysfs attributes related to the SNC device */ +for (item = sony_nc_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_nc_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_nc_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 ) { + result = +device_create_file (&sony_pf_device->dev, + &item->devattr); +if (result) + goto out_sysfs; + } + } + printk(KERN_INFO SONY_NC_DRIVER_NAME " successfully installed\n");return 0 ; + out_sysfs: +for (item = sony_nc_values; item->name; ++item) { +device_remove_file (&sony_pf_device->dev, &item->devattr); + } +sony_pf_remove (); outbacklight:if (sony_backlight_device)backlight_device_unregister (sony_backlight_device);
@@ -520,6 +527,7 @@ static int sony_nc_add(struct acpi_devicstatic int sony_nc_remove (struct acpi_device *device,int type) {acpi_status status; +struct sony_nc_value *item;if (sony_backlight_device)backlight_device_unregister (sony_backlight_device);
@@ -532,7 +540,11 @@ static int sony_nc_remove(struct acpi_deif (ACPI_FAILURE (status))printk (LOG_PFX "unable to remove notify handler\n" ); -sony_nc_pf_remove (); +for (item = sony_nc_values; item->name; ++item) { +device_remove_file (&sony_pf_device->dev, &item->devattr); + } + +sony_pf_remove (); printk(KERN_INFO SONY_NC_DRIVER_NAME " successfully removed\n");
--
Signature · 2 lines
mattia :wq!
PATCH 3/9 Add debug macros also used by the sonypi reimplementation
In reply to a message not in the archive--- drivers/misc/sony-laptop.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
drivers/misc/sony-laptop.c +10 -10
@@ -35,6 +35,11 @@#include <acpi/acpi_bus.h> #include <asm/uaccess.h> +#define LOG_PFX KERN_WARNING "sony-laptop: " +#define dprintk(msg...) do { \ + if (debug) printk(KERN_WARNING LOG_PFX msg); \ +} while (0) +#define SONY_NC_CLASS "sony"#define SONY_NC_HID "SNY5001"#define SONY_NC_DRIVER_NAME "ACPI Sony Notebook Control Driver v0.4"
@@ -43,8 +48,6 @@0-based values */ #define SONY_MAX_BRIGHTNESS 8 -#define LOG_PFX KERN_WARNING "sony-laptop: " -MODULE_AUTHOR ("Stelian Pop, Mattia Dongili" );MODULE_DESCRIPTION (SONY_NC_DRIVER_NAME );MODULE_LICENSE ("GPL" );
@@ -368,8 +371,7 @@ static struct backlight_ops sony_backlig*/ static void sony_acpi_notify (acpi_handle handle,u32 event,void *data) { -if (debug) -printk (LOG_PFX "sony_acpi_notify, event: %d\n" , event); +dprintk ("sony_acpi_notify, event: %d\n" , event);acpi_bus_generate_event (sony_nc_acpi_device,1 , event); }
@@ -472,9 +474,8 @@ static int sony_nc_add(struct acpi_devicif (ACPI_SUCCESS (acpi_get_handle (sony_nc_acpi_handle, *item->acpiget, &handle))) { -if (debug) -printk (LOG_PFX "Found %s getter: %s\n" , - item->name, *item->acpiget); +dprintk ("Found %s getter: %s\n" , + item->name, *item->acpiget); item->devattr.attr.mode |=S_IRUGO ;break ; }
@@ -485,9 +486,8 @@ static int sony_nc_add(struct acpi_devicif (ACPI_SUCCESS (acpi_get_handle (sony_nc_acpi_handle, *item->acpiset, &handle))) { -if (debug) -printk (LOG_PFX "Found %s setter: %s\n" , - item->name, *item->acpiset); +dprintk ("Found %s setter: %s\n" , + item->name, *item->acpiset); item->devattr.attr.mode |=S_IWUSR ;break ; }
--
Signature · 2 lines
mattia :wq!
PATCH 4/9 Add SNY6001 device handling (sonypi reimplementation)
In reply to a message not in the archiveReimplement sonypi using ACPI only functions.
--- drivers/misc/sony-laptop.c | 1078 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1065 insertions(+), 13 deletions(-)
drivers/misc/sony-laptop.c +1072 -13
@@ -1,5 +1,5 @@/* -* ACPI Sony Notebook Control Driver (SNC) +* ACPI Sony Notebook Control Driver (SNC and SPIC) * * Copyright (C) 2004-2005 Stelian Pop <[email protected]> * Copyright (C) 2007 Mattia Dongili <[email protected]>
@@ -7,6 +7,25 @@* Parts of this driver inspired from asus_acpi.c and ibm_acpi.c * which are copyrighted by their respective authors. * +* The SNY6001 driver part is based on the sonypi driver which includes +* material from: +* +* Copyright (C) 2001-2005 Stelian Pop <[email protected]> +* +* Copyright (C) 2005 Narayanan R S <[email protected]> +* +* Copyright (C) 2001-2002 Alc�ve <www.alcove.com> +* +* Copyright (C) 2001 Michael Ashley <[email protected]> +* +* Copyright (C) 2001 Junichi Morita <[email protected]> +* +* Copyright (C) 2000 Takaya Kinjo <[email protected]> +* +* Copyright (C) 2000 Andrew Tridgell <[email protected]> +* +* Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras. +* * 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
@@ -31,32 +50,65 @@#include <linux/backlight.h> #include <linux/platform_device.h> #include <linux/err.h> +#include <linux/dmi.h> +#include <linux/pci.h> +#include <linux/interrupt.h> +#include <linux/delay.h> +#include <linux/input.h> +#include <linux/kfifo.h> +#include <linux/workqueue.h> +#include <linux/acpi.h> #include <acpi/acpi_drivers.h> #include <acpi/acpi_bus.h> #include <asm/uaccess.h> +#include <linux/sonypi.h> -#define LOG_PFX KERN_WARNING "sony-laptop: " +#define DRV_PFX "sony-laptop: " +#define LOG_PFX KERN_WARNING DRV_PFX #define dprintk(msg...) do { \ - if (debug) printk(KERN_WARNING LOG_PFX msg); \ + if (debug) printk(LOG_PFX msg); \ } while (0) -#define SONY_NC_CLASS "sony" +#define SONY_LAPTOP_DRIVER_VERSION "0.5" + +#define SONY_NC_CLASS "sony-nc"#define SONY_NC_HID "SNY5001" -#define SONY_NC_DRIVER_NAME "ACPI Sony Notebook Control Driver v0.4" +#define SONY_NC_DRIVER_NAME "Sony Notebook Control" -/* the device uses 1-based values, while the backlight subsystem uses -0-based values */ -#define SONY_MAX_BRIGHTNESS 8 +#define SONY_PIC_CLASS "sony-pic" +#define SONY_PIC_HID "SNY6001" +#define SONY_PIC_DRIVER_NAME "Sony Programmable IO Control"MODULE_AUTHOR ("Stelian Pop, Mattia Dongili" ); -MODULE_DESCRIPTION (SONY_NC_DRIVER_NAME ); +MODULE_DESCRIPTION ("Sony laptop extras driver (SPIC and SNC ACPI device)" );MODULE_LICENSE ("GPL" ); +MODULE_VERSION (SONY_LAPTOP_DRIVER_VERSION );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 int no_spic;/* = 0 */ +module_param (no_spic, int,0444 ); +MODULE_PARM_DESC (no_spic, +"set this if you don't want to enable the SPIC device" ); + +static int compat;/* = 0 */ +module_param (compat, int,0444 ); +MODULE_PARM_DESC (compat, +"set this if you want to enable backward compatibility mode" ); + +static int force_jog;/* = 0 */ +module_param (force_jog, int,0444 ); +MODULE_PARM_DESC (force_jog, +"set this if the driver doesn't detect your jogdial" ); + +static unsigned long mask =0xffffffff ; +module_param (mask, ulong,0644 ); +MODULE_PARM_DESC (mask, +"set this to the mask of event you want to enable (see doc)" ); +/*********** Platform Device ***********/ static atomic_t sony_pf_users =ATOMIC_INIT (0 );
@@ -115,6 +167,13 @@ static void sony_pf_remove(void)/*********** SNC (SNY5001) Device ***********/ +/* the device uses 1-based values, while the backlight subsystem uses +0-based values */ +#define SONY_MAX_BRIGHTNESS 8 + +#define SNC_VALIDATE_IN 0 +#define SNC_VALIDATE_OUT 1 +static ssize_t sony_nc_sysfs_show (struct device *,struct device_attribute *,char *); static ssize_t sony_nc_sysfs_store(struct device *, struct device_attribute *,
@@ -122,9 +181,6 @@ static ssize_t sony_nc_sysfs_store(strucstatic int boolean_validate (const int ,const int );static int brightness_default_validate (const int ,const int ); -#define SNC_VALIDATE_IN 0 -#define SNC_VALIDATE_OUT 1 -struct sony_nc_value {char *name;/* name of the entry */ char **acpiget;/* names of the ACPI get function */
@@ -420,6 +476,7 @@ static int sony_nc_add(struct acpi_devicstruct sony_nc_value *item; sony_nc_acpi_device = device; +strcpy (acpi_device_class (device),"sony/hotkey" ); sony_nc_acpi_handle = device->handle;
@@ -555,6 +612,7 @@ static struct acpi_driver sony_nc_driver .name = SONY_NC_DRIVER_NAME, .class = SONY_NC_CLASS, .ids = SONY_NC_HID, + .owner = THIS_MODULE, .ops = { .add = sony_nc_add, .remove = sony_nc_remove,
@@ -562,14 +620,1015 @@ static struct acpi_driver sony_nc_driver }, }; +/*********** SPIC (SNY6001) Device ***********/ + +#define SONYPI_DEVICE_TYPE1 0x00000001 +#define SONYPI_DEVICE_TYPE2 0x00000002 +#define SONYPI_DEVICE_TYPE3 0x00000004 + +#define SONY_EC_JOGB 0x82 +#define SONY_EC_JOGB_MASK 0x02 + +#define SONY_PIC_EV_MASK 0xff + +#define SONYPI_BUF_SIZE 128 + +struct sony_pic_ioport { +struct acpi_resource_io io; +struct list_head list; +}; + +struct sony_pic_irq { +struct acpi_resource_irq irq; +struct list_head list; +}; + +struct sony_pic_dev { +int model; +struct acpi_device *acpi_dev; +struct sony_pic_irq *cur_irq; +struct sony_pic_ioport *cur_ioport; +struct list_head interrupts; +struct list_head ioports; + +struct input_dev *input_jog_dev; +struct input_dev *input_key_dev; +struct kfifo *input_fifo; +spinlock_t input_fifo_lock; +struct workqueue_struct *sony_pic_wq; +}; + +static struct sony_pic_dev spic_dev = { + .interrupts =LIST_HEAD_INIT (spic_dev.interrupts), + .ioports =LIST_HEAD_INIT (spic_dev.ioports), +}; + +/* Event masks */ +#define SONYPI_JOGGER_MASK 0x00000001 +#define SONYPI_CAPTURE_MASK 0x00000002 +#define SONYPI_FNKEY_MASK 0x00000004 +#define SONYPI_BLUETOOTH_MASK 0x00000008 +#define SONYPI_PKEY_MASK 0x00000010 +#define SONYPI_BACK_MASK 0x00000020 +#define SONYPI_HELP_MASK 0x00000040 +#define SONYPI_LID_MASK 0x00000080 +#define SONYPI_ZOOM_MASK 0x00000100 +#define SONYPI_THUMBPHRASE_MASK 0x00000200 +#define SONYPI_MEYE_MASK 0x00000400 +#define SONYPI_MEMORYSTICK_MASK 0x00000800 +#define SONYPI_BATTERY_MASK 0x00001000 +#define SONYPI_WIRELESS_MASK 0x00002000 + +struct sonypi_event { +u8 data; +u8 event; +}; + +/* The set of possible button release events */ +static struct sonypi_event sonypi_releaseev[] = { + {0x00 ,SONYPI_EVENT_ANYBUTTON_RELEASED }, + {0 ,0 } +}; + +/* The set of possible jogger events */ +static struct sonypi_event sonypi_joggerev[] = { + {0x1f ,SONYPI_EVENT_JOGDIAL_UP }, + {0x01 ,SONYPI_EVENT_JOGDIAL_DOWN }, + {0x5f ,SONYPI_EVENT_JOGDIAL_UP_PRESSED }, + {0x41 ,SONYPI_EVENT_JOGDIAL_DOWN_PRESSED }, + {0x1e ,SONYPI_EVENT_JOGDIAL_FAST_UP }, + {0x02 ,SONYPI_EVENT_JOGDIAL_FAST_DOWN }, + {0x5e ,SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED }, + {0x42 ,SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED }, + {0x1d ,SONYPI_EVENT_JOGDIAL_VFAST_UP }, + {0x03 ,SONYPI_EVENT_JOGDIAL_VFAST_DOWN }, + {0x5d ,SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED }, + {0x43 ,SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED }, + {0x40 ,SONYPI_EVENT_JOGDIAL_PRESSED }, + {0 ,0 } +}; + +/* The set of possible capture button events */ +static struct sonypi_event sonypi_captureev[] = { + {0x05 ,SONYPI_EVENT_CAPTURE_PARTIALPRESSED }, + {0x07 ,SONYPI_EVENT_CAPTURE_PRESSED }, + {0x01 ,SONYPI_EVENT_CAPTURE_PARTIALRELEASED }, + {0 ,0 } +}; + +/* The set of possible fnkeys events */ +static struct sonypi_event sonypi_fnkeyev[] = { + {0x10 ,SONYPI_EVENT_FNKEY_ESC }, + {0x11 ,SONYPI_EVENT_FNKEY_F1 }, + {0x12 ,SONYPI_EVENT_FNKEY_F2 }, + {0x13 ,SONYPI_EVENT_FNKEY_F3 }, + {0x14 ,SONYPI_EVENT_FNKEY_F4 }, + {0x15 ,SONYPI_EVENT_FNKEY_F5 }, + {0x16 ,SONYPI_EVENT_FNKEY_F6 }, + {0x17 ,SONYPI_EVENT_FNKEY_F7 }, + {0x18 ,SONYPI_EVENT_FNKEY_F8 }, + {0x19 ,SONYPI_EVENT_FNKEY_F9 }, + {0x1a ,SONYPI_EVENT_FNKEY_F10 }, + {0x1b ,SONYPI_EVENT_FNKEY_F11 }, + {0x1c ,SONYPI_EVENT_FNKEY_F12 }, + {0x1f ,SONYPI_EVENT_FNKEY_RELEASED }, + {0x21 ,SONYPI_EVENT_FNKEY_1 }, + {0x22 ,SONYPI_EVENT_FNKEY_2 }, + {0x31 ,SONYPI_EVENT_FNKEY_D }, + {0x32 ,SONYPI_EVENT_FNKEY_E }, + {0x33 ,SONYPI_EVENT_FNKEY_F }, + {0x34 ,SONYPI_EVENT_FNKEY_S }, + {0x35 ,SONYPI_EVENT_FNKEY_B }, + {0x36 ,SONYPI_EVENT_FNKEY_ONLY }, + {0 ,0 } +}; + +/* The set of possible program key events */ +static struct sonypi_event sonypi_pkeyev[] = { + {0x01 ,SONYPI_EVENT_PKEY_P1 }, + {0x02 ,SONYPI_EVENT_PKEY_P2 }, + {0x04 ,SONYPI_EVENT_PKEY_P3 }, + {0x5c ,SONYPI_EVENT_PKEY_P1 }, + {0 ,0 } +}; + +/* The set of possible bluetooth events */ +static struct sonypi_event sonypi_blueev[] = { + {0x55 ,SONYPI_EVENT_BLUETOOTH_PRESSED }, + {0x59 ,SONYPI_EVENT_BLUETOOTH_ON }, + {0x5a ,SONYPI_EVENT_BLUETOOTH_OFF }, + {0 ,0 } +}; + +/* The set of possible wireless events */ +static struct sonypi_event sonypi_wlessev[] = { + {0x59 ,SONYPI_EVENT_WIRELESS_ON }, + {0x5a ,SONYPI_EVENT_WIRELESS_OFF }, + {0 ,0 } +}; + +/* The set of possible back button events */ +static struct sonypi_event sonypi_backev[] = { + {0x20 ,SONYPI_EVENT_BACK_PRESSED }, + {0 ,0 } +}; + +/* The set of possible help button events */ +static struct sonypi_event sonypi_helpev[] = { + {0x3b ,SONYPI_EVENT_HELP_PRESSED }, + {0 ,0 } +}; + + +/* The set of possible lid events */ +static struct sonypi_event sonypi_lidev[] = { + {0x51 ,SONYPI_EVENT_LID_CLOSED }, + {0x50 ,SONYPI_EVENT_LID_OPENED }, + {0 ,0 } +}; + +/* The set of possible zoom events */ +static struct sonypi_event sonypi_zoomev[] = { + {0x39 ,SONYPI_EVENT_ZOOM_PRESSED }, + {0 ,0 } +}; + +/* The set of possible thumbphrase events */ +static struct sonypi_event sonypi_thumbphraseev[] = { + {0x3a ,SONYPI_EVENT_THUMBPHRASE_PRESSED }, + {0 ,0 } +}; + +/* The set of possible motioneye camera events */ +static struct sonypi_event sonypi_meyeev[] = { + {0x00 ,SONYPI_EVENT_MEYE_FACE }, + {0x01 ,SONYPI_EVENT_MEYE_OPPOSITE }, + {0 ,0 } +}; + +/* The set of possible memorystick events */ +static struct sonypi_event sonypi_memorystickev[] = { + {0x53 ,SONYPI_EVENT_MEMORYSTICK_INSERT }, + {0x54 ,SONYPI_EVENT_MEMORYSTICK_EJECT }, + {0 ,0 } +}; + +/* The set of possible battery events */ +static struct sonypi_event sonypi_batteryev[] = { + {0x20 ,SONYPI_EVENT_BATTERY_INSERT }, + {0x30 ,SONYPI_EVENT_BATTERY_REMOVE }, + {0 ,0 } +}; + +static struct sonypi_eventtypes { +int model; +u8 data; +unsigned long mask; +struct sonypi_event * events; +} sony_pic_eventtypes[] = { + {SONYPI_DEVICE_TYPE1 ,0 ,0xffffffff , sonypi_releaseev }, + {SONYPI_DEVICE_TYPE1 ,0x70 ,SONYPI_MEYE_MASK , sonypi_meyeev }, + {SONYPI_DEVICE_TYPE1 ,0x30 ,SONYPI_LID_MASK , sonypi_lidev }, + {SONYPI_DEVICE_TYPE1 ,0x60 ,SONYPI_CAPTURE_MASK , sonypi_captureev }, + {SONYPI_DEVICE_TYPE1 ,0x10 ,SONYPI_JOGGER_MASK , sonypi_joggerev }, + {SONYPI_DEVICE_TYPE1 ,0x20 ,SONYPI_FNKEY_MASK , sonypi_fnkeyev }, + {SONYPI_DEVICE_TYPE1 ,0x30 ,SONYPI_BLUETOOTH_MASK , sonypi_blueev }, + {SONYPI_DEVICE_TYPE1 ,0x40 ,SONYPI_PKEY_MASK , sonypi_pkeyev }, + {SONYPI_DEVICE_TYPE1 ,0x30 ,SONYPI_MEMORYSTICK_MASK , sonypi_memorystickev }, + {SONYPI_DEVICE_TYPE1 ,0x40 ,SONYPI_BATTERY_MASK , sonypi_batteryev }, + + {SONYPI_DEVICE_TYPE2 ,0 ,0xffffffff , sonypi_releaseev }, + {SONYPI_DEVICE_TYPE2 ,0x38 ,SONYPI_LID_MASK , sonypi_lidev }, + {SONYPI_DEVICE_TYPE2 ,0x11 ,SONYPI_JOGGER_MASK , sonypi_joggerev }, + {SONYPI_DEVICE_TYPE2 ,0x61 ,SONYPI_CAPTURE_MASK , sonypi_captureev }, + {SONYPI_DEVICE_TYPE2 ,0x21 ,SONYPI_FNKEY_MASK , sonypi_fnkeyev }, + {SONYPI_DEVICE_TYPE2 ,0x31 ,SONYPI_BLUETOOTH_MASK , sonypi_blueev }, + {SONYPI_DEVICE_TYPE2 ,0x08 ,SONYPI_PKEY_MASK , sonypi_pkeyev }, + {SONYPI_DEVICE_TYPE2 ,0x11 ,SONYPI_BACK_MASK , sonypi_backev }, + {SONYPI_DEVICE_TYPE2 ,0x21 ,SONYPI_HELP_MASK , sonypi_helpev }, + {SONYPI_DEVICE_TYPE2 ,0x21 ,SONYPI_ZOOM_MASK , sonypi_zoomev }, + {SONYPI_DEVICE_TYPE2 ,0x20 ,SONYPI_THUMBPHRASE_MASK , sonypi_thumbphraseev }, + {SONYPI_DEVICE_TYPE2 ,0x31 ,SONYPI_MEMORYSTICK_MASK , sonypi_memorystickev }, + {SONYPI_DEVICE_TYPE2 ,0x41 ,SONYPI_BATTERY_MASK , sonypi_batteryev }, + {SONYPI_DEVICE_TYPE2 ,0x31 ,SONYPI_PKEY_MASK , sonypi_pkeyev }, + + {SONYPI_DEVICE_TYPE3 ,0 ,0xffffffff , sonypi_releaseev }, + {SONYPI_DEVICE_TYPE3 ,0x21 ,SONYPI_FNKEY_MASK , sonypi_fnkeyev }, + {SONYPI_DEVICE_TYPE3 ,0x31 ,SONYPI_WIRELESS_MASK , sonypi_wlessev }, + {SONYPI_DEVICE_TYPE3 ,0x31 ,SONYPI_MEMORYSTICK_MASK , sonypi_memorystickev }, + {SONYPI_DEVICE_TYPE3 ,0x41 ,SONYPI_BATTERY_MASK , sonypi_batteryev }, + {SONYPI_DEVICE_TYPE3 ,0x31 ,SONYPI_PKEY_MASK , sonypi_pkeyev }, + {0 } +}; + +static int sony_pic_detect_device_type (void ) +{ +struct pci_dev *pcidev; +int model =0 ; + +if ((pcidev =pci_get_device (PCI_VENDOR_ID_INTEL , +PCI_DEVICE_ID_INTEL_82371AB_3 ,NULL ))) + model =SONYPI_DEVICE_TYPE1 ; + +else if ((pcidev =pci_get_device (PCI_VENDOR_ID_INTEL , +PCI_DEVICE_ID_INTEL_ICH6_1 ,NULL ))) + model =SONYPI_DEVICE_TYPE3 ; + +else if ((pcidev =pci_get_device (PCI_VENDOR_ID_INTEL , +PCI_DEVICE_ID_INTEL_ICH7_1 ,NULL ))) + model =SONYPI_DEVICE_TYPE3 ; + +else + model =SONYPI_DEVICE_TYPE2 ; + +if (pcidev) +pci_dev_put (pcidev); + + printk(KERN_INFO DRV_PFX "detected Type%d model\n", + model ==SONYPI_DEVICE_TYPE1 ?1 : + model == SONYPI_DEVICE_TYPE2 ? 2 : 3); +return model; +} + +#define ITERATIONS_LONG 10000 +#define ITERATIONS_SHORT 10 +#define wait_on_command (command, iterations) { \ + unsigned int n = iterations; \ + while (--n && (command)) \ + udelay(1); \ + if (!n) \ + dprintk("command failed at %s : %s (line %d)\n", \ + __FILE__, __FUNCTION__, __LINE__); \ +} + +static u8 sony_pic_call1 (u8 dev) +{ +u8 v1, v2; + +wait_on_command (inb_p (spic_dev.cur_ioport->io.minimum +4 ) &2 , +ITERATIONS_LONG ); +outb (dev, spic_dev.cur_ioport->io.minimum +4 ); + v1 =inb_p (spic_dev.cur_ioport->io.minimum +4 ); + v2 =inb_p (spic_dev.cur_ioport->io.minimum); +dprintk ("sony_pic_call1: 0x%.4x\n" , (v2 <<8 ) | v1); +return v2; +} + +static u8 sony_pic_call2 (u8 dev,u8 fn) +{ +u8 v1; + +wait_on_command (inb_p (spic_dev.cur_ioport->io.minimum +4 ) &2 , +ITERATIONS_LONG ); +outb (dev, spic_dev.cur_ioport->io.minimum +4 ); +wait_on_command (inb_p (spic_dev.cur_ioport->io.minimum +4 ) &2 , +ITERATIONS_LONG ); +outb (fn, spic_dev.cur_ioport->io.minimum); + v1 =inb_p (spic_dev.cur_ioport->io.minimum); +dprintk ("sony_pic_call2: 0x%.4x\n" , v1); +return v1; +} + +/***************** +* +* INPUT Device +* +*****************/ +struct sony_pic_keypress { +struct input_dev *dev; +int key; +}; + +/* Correspondance table between sonypi events and input layer events */ +static struct { +int sonypiev; +int inputev; +} sony_pic_inputkeys[] = { + {SONYPI_EVENT_CAPTURE_PRESSED ,KEY_CAMERA }, + {SONYPI_EVENT_FNKEY_ONLY ,KEY_FN }, + {SONYPI_EVENT_FNKEY_ESC ,KEY_FN_ESC }, + {SONYPI_EVENT_FNKEY_F1 ,KEY_FN_F1 }, + {SONYPI_EVENT_FNKEY_F2 ,KEY_FN_F2 }, + {SONYPI_EVENT_FNKEY_F3 ,KEY_FN_F3 }, + {SONYPI_EVENT_FNKEY_F4 ,KEY_FN_F4 }, + {SONYPI_EVENT_FNKEY_F5 ,KEY_FN_F5 }, + {SONYPI_EVENT_FNKEY_F6 ,KEY_FN_F6 }, + {SONYPI_EVENT_FNKEY_F7 ,KEY_FN_F7 }, + {SONYPI_EVENT_FNKEY_F8 ,KEY_FN_F8 }, + {SONYPI_EVENT_FNKEY_F9 ,KEY_FN_F9 }, + {SONYPI_EVENT_FNKEY_F10 ,KEY_FN_F10 }, + {SONYPI_EVENT_FNKEY_F11 ,KEY_FN_F11 }, + {SONYPI_EVENT_FNKEY_F12 ,KEY_FN_F12 }, + {SONYPI_EVENT_FNKEY_1 ,KEY_FN_1 }, + {SONYPI_EVENT_FNKEY_2 ,KEY_FN_2 }, + {SONYPI_EVENT_FNKEY_D ,KEY_FN_D }, + {SONYPI_EVENT_FNKEY_E ,KEY_FN_E }, + {SONYPI_EVENT_FNKEY_F ,KEY_FN_F }, + {SONYPI_EVENT_FNKEY_S ,KEY_FN_S }, + {SONYPI_EVENT_FNKEY_B ,KEY_FN_B }, + {SONYPI_EVENT_BLUETOOTH_PRESSED ,KEY_BLUE }, + {SONYPI_EVENT_BLUETOOTH_ON ,KEY_BLUE }, + {SONYPI_EVENT_PKEY_P1 ,KEY_PROG1 }, + {SONYPI_EVENT_PKEY_P2 ,KEY_PROG2 }, + {SONYPI_EVENT_PKEY_P3 ,KEY_PROG3 }, + {SONYPI_EVENT_BACK_PRESSED ,KEY_BACK }, + {SONYPI_EVENT_HELP_PRESSED ,KEY_HELP }, + {SONYPI_EVENT_ZOOM_PRESSED ,KEY_ZOOM }, + {SONYPI_EVENT_THUMBPHRASE_PRESSED ,BTN_THUMB }, + {0 ,0 }, +}; + +/* release buttons after a short delay if pressed */ +static void do_sony_pic_release_key (struct work_struct *work) +{ +struct sony_pic_keypress kp; + +while (kfifo_get (spic_dev.input_fifo, (unsigned char *)&kp, +sizeof (kp)) ==sizeof (kp)) { +msleep (10 ); +input_report_key (kp.dev, kp.key,0 ); +input_sync (kp.dev); + } +} +static DECLARE_WORK(sony_pic_release_key_work, + do_sony_pic_release_key); + +/* forward event to the input subsytem */ +static void sony_pic_report_input_event (u8 event) +{ +struct input_dev *jog_dev = spic_dev.input_jog_dev; +struct input_dev *key_dev = spic_dev.input_key_dev; +struct sony_pic_keypress kp = {NULL }; +int i; + +if (event ==SONYPI_EVENT_FNKEY_RELEASED ) { +/* Nothing, not all VAIOs generate this event */ +return ; + } + +/* report jog_dev events */ +if (jog_dev) { +switch (event) { +case SONYPI_EVENT_JOGDIAL_UP : +case SONYPI_EVENT_JOGDIAL_UP_PRESSED : +input_report_rel (jog_dev,REL_WHEEL ,1 ); +input_sync (jog_dev); +return ; + +case SONYPI_EVENT_JOGDIAL_DOWN : +case SONYPI_EVENT_JOGDIAL_DOWN_PRESSED : +input_report_rel (jog_dev,REL_WHEEL ,-1 ); +input_sync (jog_dev); +return ; + +default : +break ; + } + } + +switch (event) { +case SONYPI_EVENT_JOGDIAL_PRESSED : + kp.key =BTN_MIDDLE ; + kp.dev = jog_dev; +break ; + +default : +for (i =0 ; sony_pic_inputkeys[i].sonypiev; i++) +if (event == sony_pic_inputkeys[i].sonypiev) { + kp.dev = key_dev; + kp.key = sony_pic_inputkeys[i].inputev; +break ; + } +break ; + } + +if (kp.dev) { +input_report_key (kp.dev, kp.key,1 ); +input_sync (kp.dev); +kfifo_put (spic_dev.input_fifo, + (unsigned char *)&kp,sizeof (kp)); + +if (!work_pending (&sony_pic_release_key_work)) +queue_work (spic_dev.sony_pic_wq, + &sony_pic_release_key_work); + } +} + +static int sony_pic_setup_input (void ) +{ +struct input_dev *jog_dev; +struct input_dev *key_dev; +int i; +int error; +u8 jog_present =0 ; + +/* kfifo */ +spin_lock_init (&spic_dev.input_fifo_lock); + spic_dev.input_fifo = +kfifo_alloc (SONYPI_BUF_SIZE ,GFP_KERNEL , + &spic_dev.input_fifo_lock); +if (IS_ERR (spic_dev.input_fifo)) { +printk (KERN_ERR "sonypi: kfifo_alloc failed\n" ); +return PTR_ERR (spic_dev.input_fifo); + } + +/* init workqueue */ + spic_dev.sony_pic_wq =create_singlethread_workqueue ("sony-pic" ); +if (!spic_dev.sony_pic_wq) { + printk(KERN_ERR DRV_PFX + "Unabe to create workqueue.\n"); + error = -ENXIO ; + goto err_free_kfifo; + } + +/* input keys */ + key_dev =input_allocate_device (); +if (!key_dev) { + error = -ENOMEM ; + goto err_destroy_wq; + } + + key_dev->name ="Sony Vaio Keys" ; + key_dev->id.bustype =BUS_ISA ; + key_dev->id.vendor =PCI_VENDOR_ID_SONY ; + +/* Initialize the Input Drivers: special keys */ + key_dev->evbit[0 ] =BIT (EV_KEY ); +for (i =0 ; sony_pic_inputkeys[i].sonypiev; i++) +if (sony_pic_inputkeys[i].inputev) +set_bit (sony_pic_inputkeys[i].inputev, key_dev->keybit); + + error =input_register_device (key_dev); +if (error) + goto err_free_keydev; + + spic_dev.input_key_dev = key_dev; + +/* jogdial - really reliable ? */ +ec_read (SONY_EC_JOGB , &jog_present); +if (jog_present &SONY_EC_JOGB_MASK || force_jog) { + jog_dev =input_allocate_device (); +if (!jog_dev) { + error = -ENOMEM ; + goto err_unregister_keydev; + } + + jog_dev->name ="Sony Vaio Jogdial" ; + jog_dev->id.bustype =BUS_ISA ; + jog_dev->id.vendor =PCI_VENDOR_ID_SONY ; + + jog_dev->evbit[0 ] =BIT (EV_KEY ) |BIT (EV_REL ); + jog_dev->keybit[LONG (BTN_MOUSE )] =BIT (BTN_MIDDLE ); + jog_dev->relbit[0 ] =BIT (REL_WHEEL ); + + error =input_register_device (jog_dev); +if (error) + goto err_free_jogdev; + + spic_dev.input_jog_dev = jog_dev; + } + +return 0 ; + +err_free_jogdev: +input_free_device (jog_dev); + +err_unregister_keydev: +input_unregister_device (key_dev); +/* to avoid kref underflow below at input_free_device */ + key_dev =NULL ; + +err_free_keydev: +input_free_device (key_dev); + +err_destroy_wq: +destroy_workqueue (spic_dev.sony_pic_wq); + +err_free_kfifo: +kfifo_free (spic_dev.input_fifo); + +return error; +} + +static void sony_pic_remove_input (void ) +{ +/* flush workqueue first */ +flush_workqueue (spic_dev.sony_pic_wq); + +/* destroy input devs */ +input_unregister_device (spic_dev.input_key_dev); + spic_dev.input_key_dev =NULL ; + +if (spic_dev.input_jog_dev) { +input_unregister_device (spic_dev.input_jog_dev); + spic_dev.input_jog_dev =NULL ; + } + +destroy_workqueue (spic_dev.sony_pic_wq); +kfifo_free (spic_dev.input_fifo); +} + +/******************** +* +* ACPI callbacks +* +********************/ +static acpi_status +sony_pic_read_possible_resource (struct acpi_resource *resource,void *context) +{ +u32 i; +struct sony_pic_dev *dev = (struct sony_pic_dev *)context; + +switch (resource->type) { +case ACPI_RESOURCE_TYPE_START_DEPENDENT : +case ACPI_RESOURCE_TYPE_END_DEPENDENT : +return AE_OK ; + +case ACPI_RESOURCE_TYPE_IRQ : + { +struct acpi_resource_irq *p = &resource->data.irq; +struct sony_pic_irq *interrupt =NULL ; +if (!p || !p->interrupt_count) { +/* +* IRQ descriptors may have no IRQ# bits set, +* particularly those those w/ _STA disabled +*/ +dprintk ("Blank IRQ resource\n" ); +return AE_OK ; + } +for (i =0 ; i < p->interrupt_count; i++) { +if (!p->interrupts[i]) { + printk(KERN_WARNING DRV_PFX +"Invalid IRQ %d\n" , + p->interrupts[i]); +continue ; + } + interrupt =kzalloc (sizeof (*interrupt), +GFP_KERNEL ); +if (!interrupt) +return AE_ERROR ; + +list_add (&interrupt->list, &dev->interrupts); + interrupt->irq.triggering = p->triggering; + interrupt->irq.polarity = p->polarity; + interrupt->irq.sharable = p->sharable; + interrupt->irq.interrupt_count =1 ; + interrupt->irq.interrupts[0 ] = p->interrupts[i]; + } +return AE_OK ; + } +case ACPI_RESOURCE_TYPE_IO : + { +struct acpi_resource_io *io = &resource->data.io; +struct sony_pic_ioport *ioport =NULL ; +if (!io) { +dprintk ("Blank IO resource\n" ); +return AE_OK ; + } + + ioport =kzalloc (sizeof (*ioport),GFP_KERNEL ); +if (!ioport) +return AE_ERROR ; + +list_add (&ioport->list, &dev->ioports); +memcpy (&ioport->io, io,sizeof (*io)); +return AE_OK ; + } +default : +dprintk ("Resource %d isn't an IRQ nor an IO port\n" , + resource->type); + +case ACPI_RESOURCE_TYPE_END_TAG : +return AE_OK ; + } +return AE_CTRL_TERMINATE ; +} + +static int sony_pic_possible_resources (struct acpi_device *device) +{ +int result =0 ; +acpi_status status =AE_OK ; + +if (!device) +return -EINVAL ; + +/* get device status */ +/* see acpi_pci_link_get_current acpi_pci_link_get_possible */ +dprintk ("Evaluating _STA\n" ); + result =acpi_bus_get_status (device); +if (result) { + printk(KERN_WARNING DRV_PFX "Unable to read status\n"); + goto end; + } + +if (!device->status.enabled) +dprintk ("Device disabled\n" ); +else +dprintk ("Device enabled\n" ); + +/* +* Query and parse 'method' +*/ +dprintk ("Evaluating %s\n" ,METHOD_NAME__PRS ); + status =acpi_walk_resources (device->handle,METHOD_NAME__PRS , + sony_pic_read_possible_resource, &spic_dev); +if (ACPI_FAILURE (status)) { + printk(KERN_WARNING DRV_PFX +"Failure evaluating %s\n" , + METHOD_NAME__PRS); + result = -ENODEV ; + } +end: +return result; +} + +/* +* Disable the spic device by calling its _DIS method +*/ +static int sony_pic_disable (struct acpi_device *device) +{ +if (ACPI_FAILURE (acpi_evaluate_object (device->handle,"_DIS" ,0 ,NULL ))) +return -ENXIO ; + +dprintk ("Device disabled\n" ); +return 0 ; +} + + +/* +* Based on drivers/acpi/pci_link.c:acpi_pci_link_set +* +* Call _SRS to set current resources +*/ +static int sony_pic_enable (struct acpi_device *device, +struct sony_pic_ioport *ioport,struct sony_pic_irq *irq) +{ +acpi_status status; +int result =0 ; +struct { +struct acpi_resource io_res; +struct acpi_resource irq_res; +struct acpi_resource end; + } *resource; +struct acpi_buffer buffer = {0 ,NULL }; + +if (!ioport || !irq) +return -EINVAL ; + +/* init acpi_buffer */ + resource =kzalloc (sizeof (*resource) +1 ,GFP_KERNEL ); +if (!resource) +return -ENOMEM ; + + buffer.length =sizeof (*resource) +1 ; + buffer.pointer = resource; + +/* setup io resource */ + resource->io_res.type =ACPI_RESOURCE_TYPE_IO ; + resource->io_res.length =sizeof (struct acpi_resource ); +memcpy (&resource->io_res.data.io, &ioport->io, +sizeof (struct acpi_resource_io )); + +/* setup irq resource */ + resource->irq_res.type =ACPI_RESOURCE_TYPE_IRQ ; + resource->irq_res.length =sizeof (struct acpi_resource ); +memcpy (&resource->irq_res.data.irq, &irq->irq, +sizeof (struct acpi_resource_irq )); +/* we requested a shared irq */ + resource->irq_res.data.irq.sharable =ACPI_SHARED ; + + resource->end.type =ACPI_RESOURCE_TYPE_END_TAG ; + +/* Attempt to set the resource */ +dprintk ("Evaluating _SRS\n" ); + status =acpi_set_current_resources (device->handle, &buffer); + +/* check for total failure */ +if (ACPI_FAILURE (status)) { + printk(KERN_ERR DRV_PFX "Error evaluating _SRS"); + result = -ENODEV ; + goto end; + } + +/* Necessary device initializations calls (from sonypi) */ +sony_pic_call1 (0x82 ); +sony_pic_call2 (0x81 ,0xff ); +sony_pic_call1 (compat ?0x92 :0x82 ); + +end: +kfree (resource); +return result; +} + +/***************** +* +* ISR: some event is available +* +*****************/ +static irqreturn_t sony_pic_irq (int irq,void *dev_id) +{ +int i, j; +u32 port_val =0 ; +u8 ev =0 ; +u8 data_mask =0 ; +u8 device_event =0 ; + +struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id; + +acpi_os_read_port (dev->cur_ioport->io.minimum, &port_val, + dev->cur_ioport->io.address_length); + ev = port_val &SONY_PIC_EV_MASK ; + data_mask =0xff & (port_val >> (dev->cur_ioport->io.address_length -8 )); + +dprintk ("event (0x%.8x [%.2x] [%.2x]) at port 0x%.4x\n" , + port_val, ev, data_mask, dev->cur_ioport->io.minimum); + +if (ev ==0x00 || ev ==0xff ) +return IRQ_HANDLED ; + +for (i =0 ; sony_pic_eventtypes[i].model; i++) { + +if (spic_dev.model != sony_pic_eventtypes[i].model) +continue ; + +if ((data_mask & sony_pic_eventtypes[i].data) != + sony_pic_eventtypes[i].data) +continue ; + +if (!(mask & sony_pic_eventtypes[i].mask)) +continue ; + +for (j =0 ; sony_pic_eventtypes[i].events[j].event; j++) { +if (ev == sony_pic_eventtypes[i].events[j].data) { + device_event = + sony_pic_eventtypes[i].events[j].event; + goto found; + } + } + } +return IRQ_HANDLED ; + +found: +sony_pic_report_input_event (device_event); +acpi_bus_generate_event (spic_dev.acpi_dev,1 , device_event); + +return IRQ_HANDLED ; +} + +/***************** +* +* ACPI driver +* +*****************/ +static int sony_pic_remove (struct acpi_device *device,int type) +{ +struct sony_pic_ioport *io, *tmp_io; +struct sony_pic_irq *irq, *tmp_irq; + +if (sony_pic_disable (device)) { + printk(KERN_ERR DRV_PFX "Couldn't disable device.\n"); +return -ENXIO ; + } + +free_irq (spic_dev.cur_irq->irq.interrupts[0 ], &spic_dev); +release_region (spic_dev.cur_ioport->io.minimum, + spic_dev.cur_ioport->io.address_length); + +sony_pic_remove_input (); + +list_for_each_entry_safe (io, tmp_io, &spic_dev.ioports, list) { +list_del (&io->list); +kfree (io); + } +list_for_each_entry_safe (irq, tmp_irq, &spic_dev.interrupts, list) { +list_del (&irq->list); +kfree (irq); + } + spic_dev.cur_ioport =NULL ; + spic_dev.cur_irq =NULL ; + +dprintk ("removed.\n" ); +return 0 ; +} + +static int sony_pic_add (struct acpi_device *device) +{ +int result; +struct sony_pic_ioport *io, *tmp_io; +struct sony_pic_irq *irq, *tmp_irq; + + printk(KERN_INFO DRV_PFX +"Sony Programmable I/O Controller Driver v%s.\n" , + SONY_LAPTOP_DRIVER_VERSION); + + spic_dev.acpi_dev = device; +strcpy (acpi_device_class (device),"sony/hotkey" ); + spic_dev.model =sony_pic_detect_device_type (); + +/* read _PRS resources */ + result =sony_pic_possible_resources (device); +if (result) { + printk(KERN_ERR DRV_PFX + "Unabe to read possible resources.\n"); + goto err_free_resources; + } + +/* setup input devices and helper fifo */ + result =sony_pic_setup_input (); +if (result) { + printk(KERN_ERR DRV_PFX + "Unabe to create input devices.\n"); + goto err_free_resources; + } + +/* request io port */ +list_for_each_entry (io, &spic_dev.ioports, list) { +if (request_region (io->io.minimum, io->io.address_length, +"Sony Programable I/O Device" )) { +dprintk ("I/O port: 0x%.4x (0x%.4x) + 0x%.2x\n" , + io->io.minimum, io->io.maximum, + io->io.address_length); + spic_dev.cur_ioport = io; +break ; + } + } +if (!spic_dev.cur_ioport) { + printk(KERN_ERR DRV_PFX "Failed to request_region.\n"); + result = -ENODEV ; + goto err_remove_input; + } + +/* request IRQ */ +list_for_each_entry (irq, &spic_dev.interrupts, list) { +if (!request_irq (irq->irq.interrupts[0 ], sony_pic_irq, +IRQF_SHARED ,"sony-laptop" , &spic_dev)) { +dprintk ("IRQ: %d - triggering: %d - " +"polarity: %d - shr: %d\n" , + irq->irq.interrupts[0 ], + irq->irq.triggering, + irq->irq.polarity, + irq->irq.sharable); + spic_dev.cur_irq = irq; +break ; + } + } +if (!spic_dev.cur_irq) { + printk(KERN_ERR DRV_PFX "Failed to request_irq.\n"); + result = -ENODEV ; + goto err_release_region; + } + +/* set resource status _SRS */ + result =sony_pic_enable (device, spic_dev.cur_ioport, spic_dev.cur_irq); +if (result) { + printk(KERN_ERR DRV_PFX "Couldn't enable device.\n"); + goto err_free_irq; + } + +return 0 ; + +err_free_irq: +free_irq (spic_dev.cur_irq->irq.interrupts[0 ], &spic_dev); + +err_release_region: +release_region (spic_dev.cur_ioport->io.minimum, + spic_dev.cur_ioport->io.address_length); + +err_remove_input: +sony_pic_remove_input (); + +err_free_resources: +list_for_each_entry_safe (io, tmp_io, &spic_dev.ioports, list) { +list_del (&io->list); +kfree (io); + } +list_for_each_entry_safe (irq, tmp_irq, &spic_dev.interrupts, list) { +list_del (&irq->list); +kfree (irq); + } + spic_dev.cur_ioport =NULL ; + spic_dev.cur_irq =NULL ; + +return result; +} + +static int sony_pic_suspend (struct acpi_device *device,pm_message_t state) +{ +if (sony_pic_disable (device)) +return -ENXIO ; +return 0 ; +} + +static int sony_pic_resume (struct acpi_device *device) +{ +sony_pic_enable (device, spic_dev.cur_ioport, spic_dev.cur_irq); +return 0 ; +} + +static struct acpi_driver sony_pic_driver = { + .name =SONY_PIC_DRIVER_NAME , + .class =SONY_PIC_CLASS , + .ids =SONY_PIC_HID , + .owner =THIS_MODULE , + .ops = { + .add = sony_pic_add, + .remove = sony_pic_remove, + .suspend = sony_pic_suspend, + .resume = sony_pic_resume, + }, +}; + +static struct dmi_system_id __initdata sonypi_dmi_table[] = { + { + .ident ="Sony Vaio" , + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"Sony Corporation" ), +DMI_MATCH (DMI_PRODUCT_NAME ,"PCG-" ), + }, + }, + { + .ident ="Sony Vaio" , + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"Sony Corporation" ), +DMI_MATCH (DMI_PRODUCT_NAME ,"VGN-" ), + }, + }, + { } +}; +static int __init sony_laptop_init (void ) { -return acpi_bus_register_driver (&sony_nc_driver); +int result; + +if (!no_spic &&dmi_check_system (sonypi_dmi_table)) { + result =acpi_bus_register_driver (&sony_pic_driver); +if (result) { + printk(KERN_ERR DRV_PFX + "Unable to register SPIC driver."); + goto out; + } + } + + result =acpi_bus_register_driver (&sony_nc_driver); +if (result) { + printk(KERN_ERR DRV_PFX "Unable to register SNC driver."); + goto out_unregister_pic; + } + +return 0 ; + +out_unregister_pic: +if (!no_spic) +acpi_bus_unregister_driver (&sony_pic_driver); +out: +return result; } static void __exit sony_laptop_exit(void) {acpi_bus_unregister_driver (&sony_nc_driver); +if (!no_spic) +acpi_bus_unregister_driver (&sony_pic_driver); }module_init (sony_laptop_init);
--
Signature · 6 lines
mattia :wq! - To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 5/9 Unify the input subsystem event forwarding
In reply to a message not in the archiveSNC and SPIC events are forwarded to the same input devices ant thus handled together.
--- drivers/misc/sony-laptop.c | 541 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 276 insertions(+), 265 deletions(-)
drivers/misc/sony-laptop.c +276 -265
@@ -97,18 +97,266 @@ MODULE_PARM_DESC(no_spic,static int compat;/* = 0 */ module_param (compat, int,0444 );MODULE_PARM_DESC (compat, -"set this if you want to enable backward compatibility mode" ); - -static int force_jog;/* = 0 */ -module_param (force_jog, int,0444 ); -MODULE_PARM_DESC (force_jog, -"set this if the driver doesn't detect your jogdial" ); +"set this if you want to enable backward compatibility mode for SPIC" );static unsigned long mask =0xffffffff ;module_param (mask, ulong,0644 );MODULE_PARM_DESC (mask,"set this to the mask of event you want to enable (see doc)" ); +/*********** Input Devices ***********/ + +#define SONY_LAPTOP_BUF_SIZE 128 +struct sony_laptop_input_s { +atomic_t users; +struct input_dev *jog_dev; +struct input_dev *key_dev; +struct kfifo *fifo; +spinlock_t fifo_lock; +struct workqueue_struct *wq; +}; +static struct sony_laptop_input_s sony_laptop_input = { + .users =ATOMIC_INIT (0 ), +}; + +struct sony_laptop_keypress { +struct input_dev *dev; +int key; +}; + +/* Correspondance table between sonypi events and input layer events */ +static struct { +int sonypiev; +int inputev; +} sony_laptop_inputkeys[] = { + {SONYPI_EVENT_CAPTURE_PRESSED ,KEY_CAMERA }, + {SONYPI_EVENT_FNKEY_ONLY ,KEY_FN }, + {SONYPI_EVENT_FNKEY_ESC ,KEY_FN_ESC }, + {SONYPI_EVENT_FNKEY_F1 ,KEY_FN_F1 }, + {SONYPI_EVENT_FNKEY_F2 ,KEY_FN_F2 }, + {SONYPI_EVENT_FNKEY_F3 ,KEY_FN_F3 }, + {SONYPI_EVENT_FNKEY_F4 ,KEY_FN_F4 }, + {SONYPI_EVENT_FNKEY_F5 ,KEY_FN_F5 }, + {SONYPI_EVENT_FNKEY_F6 ,KEY_FN_F6 }, + {SONYPI_EVENT_FNKEY_F7 ,KEY_FN_F7 }, + {SONYPI_EVENT_FNKEY_F8 ,KEY_FN_F8 }, + {SONYPI_EVENT_FNKEY_F9 ,KEY_FN_F9 }, + {SONYPI_EVENT_FNKEY_F10 ,KEY_FN_F10 }, + {SONYPI_EVENT_FNKEY_F11 ,KEY_FN_F11 }, + {SONYPI_EVENT_FNKEY_F12 ,KEY_FN_F12 }, + {SONYPI_EVENT_FNKEY_1 ,KEY_FN_1 }, + {SONYPI_EVENT_FNKEY_2 ,KEY_FN_2 }, + {SONYPI_EVENT_FNKEY_D ,KEY_FN_D }, + {SONYPI_EVENT_FNKEY_E ,KEY_FN_E }, + {SONYPI_EVENT_FNKEY_F ,KEY_FN_F }, + {SONYPI_EVENT_FNKEY_S ,KEY_FN_S }, + {SONYPI_EVENT_FNKEY_B ,KEY_FN_B }, + {SONYPI_EVENT_BLUETOOTH_PRESSED ,KEY_BLUE }, + {SONYPI_EVENT_BLUETOOTH_ON ,KEY_BLUE }, + {SONYPI_EVENT_PKEY_P1 ,KEY_PROG1 }, + {SONYPI_EVENT_PKEY_P2 ,KEY_PROG2 }, + {SONYPI_EVENT_PKEY_P3 ,KEY_PROG3 }, + {SONYPI_EVENT_BACK_PRESSED ,KEY_BACK }, + {SONYPI_EVENT_HELP_PRESSED ,KEY_HELP }, + {SONYPI_EVENT_ZOOM_PRESSED ,KEY_ZOOM }, + {SONYPI_EVENT_THUMBPHRASE_PRESSED ,BTN_THUMB }, + {0 ,0 }, +}; + +/* release buttons after a short delay if pressed */ +static void do_sony_laptop_release_key (struct work_struct *work) +{ +struct sony_laptop_keypress kp; + +while (kfifo_get (sony_laptop_input.fifo, (unsigned char *)&kp, +sizeof (kp)) ==sizeof (kp)) { +msleep (10 ); +input_report_key (kp.dev, kp.key,0 ); +input_sync (kp.dev); + } +} +static DECLARE_WORK(sony_laptop_release_key_work, + do_sony_laptop_release_key); + +/* forward event to the input subsytem */ +static void sony_laptop_report_input_event (u8 event) +{ +struct input_dev *jog_dev = sony_laptop_input.jog_dev; +struct input_dev *key_dev = sony_laptop_input.key_dev; +struct sony_laptop_keypress kp = {NULL }; +int i; + +if (event ==SONYPI_EVENT_FNKEY_RELEASED ) { +/* Nothing, not all VAIOs generate this event */ +return ; + } + +/* report events */ +switch (event) { +/* jog_dev events */ +case SONYPI_EVENT_JOGDIAL_UP : +case SONYPI_EVENT_JOGDIAL_UP_PRESSED : +input_report_rel (jog_dev,REL_WHEEL ,1 ); +input_sync (jog_dev); +return ; + +case SONYPI_EVENT_JOGDIAL_DOWN : +case SONYPI_EVENT_JOGDIAL_DOWN_PRESSED : +input_report_rel (jog_dev,REL_WHEEL ,-1 ); +input_sync (jog_dev); +return ; + +/* key_dev events */ +case SONYPI_EVENT_JOGDIAL_PRESSED : + kp.key =BTN_MIDDLE ; + kp.dev = jog_dev; +break ; + +default : +for (i =0 ; sony_laptop_inputkeys[i].sonypiev; i++) +if (event == sony_laptop_inputkeys[i].sonypiev) { + kp.dev = key_dev; + kp.key = sony_laptop_inputkeys[i].inputev; +break ; + } +break ; + } + +if (kp.dev) { +input_report_key (kp.dev, kp.key,1 ); +input_sync (kp.dev); +kfifo_put (sony_laptop_input.fifo, + (unsigned char *)&kp,sizeof (kp)); + +if (!work_pending (&sony_laptop_release_key_work)) +queue_work (sony_laptop_input.wq, + &sony_laptop_release_key_work); + }else +dprintk ("unknown input event %.2x\n" , event); +} + +static int sony_laptop_setup_input (void ) +{ +struct input_dev *jog_dev; +struct input_dev *key_dev; +int i; +int error; + +/* don't run again if already initialized */ +if (atomic_add_return (1 , &sony_laptop_input.users) >1 ) +return 0 ; + +/* kfifo */ +spin_lock_init (&sony_laptop_input.fifo_lock); + sony_laptop_input.fifo = +kfifo_alloc (SONY_LAPTOP_BUF_SIZE ,GFP_KERNEL , + &sony_laptop_input.fifo_lock); +if (IS_ERR (sony_laptop_input.fifo)) { + printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n"); + error =PTR_ERR (sony_laptop_input.fifo); + goto err_dec_users; + } + +/* init workqueue */ + sony_laptop_input.wq =create_singlethread_workqueue ("sony-laptop" ); +if (!sony_laptop_input.wq) { + printk(KERN_ERR DRV_PFX + "Unabe to create workqueue.\n"); + error = -ENXIO ; + goto err_free_kfifo; + } + +/* input keys */ + key_dev =input_allocate_device (); +if (!key_dev) { + error = -ENOMEM ; + goto err_destroy_wq; + } + + key_dev->name ="Sony Vaio Keys" ; + key_dev->id.bustype =BUS_ISA ; + key_dev->id.vendor =PCI_VENDOR_ID_SONY ; + +/* Initialize the Input Drivers: special keys */ + key_dev->evbit[0 ] =BIT (EV_KEY ); +for (i =0 ; sony_laptop_inputkeys[i].sonypiev; i++) +if (sony_laptop_inputkeys[i].inputev) +set_bit (sony_laptop_inputkeys[i].inputev, + key_dev->keybit); + + error =input_register_device (key_dev); +if (error) + goto err_free_keydev; + + sony_laptop_input.key_dev = key_dev; + +/* jogdial */ + jog_dev =input_allocate_device (); +if (!jog_dev) { + error = -ENOMEM ; + goto err_unregister_keydev; + } + + jog_dev->name ="Sony Vaio Jogdial" ; + jog_dev->id.bustype =BUS_ISA ; + jog_dev->id.vendor =PCI_VENDOR_ID_SONY ; + + jog_dev->evbit[0 ] =BIT (EV_KEY ) |BIT (EV_REL ); + jog_dev->keybit[LONG (BTN_MOUSE )] =BIT (BTN_MIDDLE ); + jog_dev->relbit[0 ] =BIT (REL_WHEEL ); + + error =input_register_device (jog_dev); +if (error) + goto err_free_jogdev; + + sony_laptop_input.jog_dev = jog_dev; + +return 0 ; + +err_free_jogdev: +input_free_device (jog_dev); + +err_unregister_keydev: +input_unregister_device (key_dev); +/* to avoid kref underflow below at input_free_device */ + key_dev =NULL ; + +err_free_keydev: +input_free_device (key_dev); + +err_destroy_wq: +destroy_workqueue (sony_laptop_input.wq); + +err_free_kfifo: +kfifo_free (sony_laptop_input.fifo); + +err_dec_users: +atomic_dec (&sony_laptop_input.users); +return error; +} + +static void sony_laptop_remove_input (void ) +{ +/* cleanup only after the last user has gone */ +if (!atomic_dec_and_test (&sony_laptop_input.users)) +return ; + +/* flush workqueue first */ +flush_workqueue (sony_laptop_input.wq); + +/* destroy input devs */ +input_unregister_device (sony_laptop_input.key_dev); + sony_laptop_input.key_dev =NULL ; + +if (sony_laptop_input.jog_dev) { +input_unregister_device (sony_laptop_input.jog_dev); + sony_laptop_input.jog_dev =NULL ; + } + +destroy_workqueue (sony_laptop_input.wq); +kfifo_free (sony_laptop_input.fifo); +} +/*********** Platform Device ***********/ static atomic_t sony_pf_users =ATOMIC_INIT (0 );
@@ -428,6 +676,7 @@ static struct backlight_ops sony_backligstatic void sony_acpi_notify (acpi_handle handle,u32 event,void *data) {dprintk ("sony_acpi_notify, event: %d\n" , event); +sony_laptop_report_input_event (event);acpi_bus_generate_event (sony_nc_acpi_device,1 , event); }
@@ -490,13 +739,21 @@ static int sony_nc_add(struct acpi_devic } } +/* setup input devices and helper fifo */ + result =sony_laptop_setup_input (); +if (result) { + printk(KERN_ERR DRV_PFX + "Unabe to create input devices.\n"); + goto outwalk; + } + status =acpi_install_notify_handler (sony_nc_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 outwalk; + goto outinput; }if (ACPI_SUCCESS (acpi_get_handle (sony_nc_acpi_handle,"GBRT" , &handle))) {
@@ -568,6 +825,7 @@ static int sony_nc_add(struct acpi_devicdevice_remove_file (&sony_pf_device->dev, &item->devattr); }sony_pf_remove (); + outbacklight:if (sony_backlight_device)backlight_device_unregister (sony_backlight_device);
@@ -577,6 +835,10 @@ static int sony_nc_add(struct acpi_devic sony_acpi_notify);if (ACPI_FAILURE (status))printk (LOG_PFX "unable to remove notify handler\n" ); + + outinput: +sony_laptop_remove_input (); + outwalk:return result; }
@@ -602,6 +864,7 @@ static int sony_nc_remove(struct acpi_de }sony_pf_remove (); +sony_laptop_remove_input (); printk(KERN_INFO SONY_NC_DRIVER_NAME " successfully removed\n");
@@ -626,13 +889,8 @@ static struct acpi_driver sony_nc_driver#define SONYPI_DEVICE_TYPE2 0x00000002#define SONYPI_DEVICE_TYPE3 0x00000004 -#define SONY_EC_JOGB 0x82 -#define SONY_EC_JOGB_MASK 0x02 -#define SONY_PIC_EV_MASK 0xff -#define SONYPI_BUF_SIZE 128 -struct sony_pic_ioport {struct acpi_resource_io io;struct list_head list;
@@ -650,12 +908,6 @@ struct sony_pic_dev {struct sony_pic_ioport *cur_ioport;struct list_head interrupts;struct list_head ioports; - -struct input_dev *input_jog_dev; -struct input_dev *input_key_dev; -struct kfifo *input_fifo; -spinlock_t input_fifo_lock; -struct workqueue_struct *sony_pic_wq; };static struct sony_pic_dev spic_dev = {
@@ -929,250 +1181,9 @@ static u8 sony_pic_call2(u8 dev, u8 fn)return v1; } -/***************** -* -* INPUT Device -* -*****************/ -struct sony_pic_keypress { -struct input_dev *dev; -int key; -}; - -/* Correspondance table between sonypi events and input layer events */ -static struct { -int sonypiev; -int inputev; -} sony_pic_inputkeys[] = { - {SONYPI_EVENT_CAPTURE_PRESSED ,KEY_CAMERA }, - {SONYPI_EVENT_FNKEY_ONLY ,KEY_FN }, - {SONYPI_EVENT_FNKEY_ESC ,KEY_FN_ESC }, - {SONYPI_EVENT_FNKEY_F1 ,KEY_FN_F1 }, - {SONYPI_EVENT_FNKEY_F2 ,KEY_FN_F2 }, - {SONYPI_EVENT_FNKEY_F3 ,KEY_FN_F3 }, - {SONYPI_EVENT_FNKEY_F4 ,KEY_FN_F4 }, - {SONYPI_EVENT_FNKEY_F5 ,KEY_FN_F5 }, - {SONYPI_EVENT_FNKEY_F6 ,KEY_FN_F6 }, - {SONYPI_EVENT_FNKEY_F7 ,KEY_FN_F7 }, - {SONYPI_EVENT_FNKEY_F8 ,KEY_FN_F8 }, - {SONYPI_EVENT_FNKEY_F9 ,KEY_FN_F9 }, - {SONYPI_EVENT_FNKEY_F10 ,KEY_FN_F10 }, - {SONYPI_EVENT_FNKEY_F11 ,KEY_FN_F11 }, - {SONYPI_EVENT_FNKEY_F12 ,KEY_FN_F12 }, - {SONYPI_EVENT_FNKEY_1 ,KEY_FN_1 }, - {SONYPI_EVENT_FNKEY_2 ,KEY_FN_2 }, - {SONYPI_EVENT_FNKEY_D ,KEY_FN_D }, - {SONYPI_EVENT_FNKEY_E ,KEY_FN_E }, - {SONYPI_EVENT_FNKEY_F ,KEY_FN_F }, - {SONYPI_EVENT_FNKEY_S ,KEY_FN_S }, - {SONYPI_EVENT_FNKEY_B ,KEY_FN_B }, - {SONYPI_EVENT_BLUETOOTH_PRESSED ,KEY_BLUE }, - {SONYPI_EVENT_BLUETOOTH_ON ,KEY_BLUE }, - {SONYPI_EVENT_PKEY_P1 ,KEY_PROG1 }, - {SONYPI_EVENT_PKEY_P2 ,KEY_PROG2 }, - {SONYPI_EVENT_PKEY_P3 ,KEY_PROG3 }, - {SONYPI_EVENT_BACK_PRESSED ,KEY_BACK }, - {SONYPI_EVENT_HELP_PRESSED ,KEY_HELP }, - {SONYPI_EVENT_ZOOM_PRESSED ,KEY_ZOOM }, - {SONYPI_EVENT_THUMBPHRASE_PRESSED ,BTN_THUMB }, - {0 ,0 }, -}; - -/* release buttons after a short delay if pressed */ -static void do_sony_pic_release_key (struct work_struct *work) -{ -struct sony_pic_keypress kp; - -while (kfifo_get (spic_dev.input_fifo, (unsigned char *)&kp, -sizeof (kp)) ==sizeof (kp)) { -msleep (10 ); -input_report_key (kp.dev, kp.key,0 ); -input_sync (kp.dev); - } -} -static DECLARE_WORK(sony_pic_release_key_work, - do_sony_pic_release_key); - -/* forward event to the input subsytem */ -static void sony_pic_report_input_event (u8 event) -{ -struct input_dev *jog_dev = spic_dev.input_jog_dev; -struct input_dev *key_dev = spic_dev.input_key_dev; -struct sony_pic_keypress kp = {NULL }; -int i; - -if (event ==SONYPI_EVENT_FNKEY_RELEASED ) { -/* Nothing, not all VAIOs generate this event */ -return ; - } - -/* report jog_dev events */ -if (jog_dev) { -switch (event) { -case SONYPI_EVENT_JOGDIAL_UP : -case SONYPI_EVENT_JOGDIAL_UP_PRESSED : -input_report_rel (jog_dev,REL_WHEEL ,1 ); -input_sync (jog_dev); -return ; - -case SONYPI_EVENT_JOGDIAL_DOWN : -case SONYPI_EVENT_JOGDIAL_DOWN_PRESSED : -input_report_rel (jog_dev,REL_WHEEL ,-1 ); -input_sync (jog_dev); -return ; - -default : -break ; - } - } - -switch (event) { -case SONYPI_EVENT_JOGDIAL_PRESSED : - kp.key =BTN_MIDDLE ; - kp.dev = jog_dev; -break ; - -default : -for (i =0 ; sony_pic_inputkeys[i].sonypiev; i++) -if (event == sony_pic_inputkeys[i].sonypiev) { - kp.dev = key_dev; - kp.key = sony_pic_inputkeys[i].inputev; -break ; - } -break ; - } - -if (kp.dev) { -input_report_key (kp.dev, kp.key,1 ); -input_sync (kp.dev); -kfifo_put (spic_dev.input_fifo, - (unsigned char *)&kp,sizeof (kp)); - -if (!work_pending (&sony_pic_release_key_work)) -queue_work (spic_dev.sony_pic_wq, - &sony_pic_release_key_work); - } -} - -static int sony_pic_setup_input (void ) -{ -struct input_dev *jog_dev; -struct input_dev *key_dev; -int i; -int error; -u8 jog_present =0 ; - -/* kfifo */ -spin_lock_init (&spic_dev.input_fifo_lock); - spic_dev.input_fifo = -kfifo_alloc (SONYPI_BUF_SIZE ,GFP_KERNEL , - &spic_dev.input_fifo_lock); -if (IS_ERR (spic_dev.input_fifo)) { -printk (KERN_ERR "sonypi: kfifo_alloc failed\n" ); -return PTR_ERR (spic_dev.input_fifo); - } - -/* init workqueue */ - spic_dev.sony_pic_wq =create_singlethread_workqueue ("sony-pic" ); -if (!spic_dev.sony_pic_wq) { - printk(KERN_ERR DRV_PFX - "Unabe to create workqueue.\n"); - error = -ENXIO ; - goto err_free_kfifo; - } - -/* input keys */ - key_dev =input_allocate_device (); -if (!key_dev) { - error = -ENOMEM ; - goto err_destroy_wq; - } - - key_dev->name ="Sony Vaio Keys" ; - key_dev->id.bustype =BUS_ISA ; - key_dev->id.vendor =PCI_VENDOR_ID_SONY ; - -/* Initialize the Input Drivers: special keys */ - key_dev->evbit[0 ] =BIT (EV_KEY ); -for (i =0 ; sony_pic_inputkeys[i].sonypiev; i++) -if (sony_pic_inputkeys[i].inputev) -set_bit (sony_pic_inputkeys[i].inputev, key_dev->keybit); - - error =input_register_device (key_dev); -if (error) - goto err_free_keydev; - - spic_dev.input_key_dev = key_dev; - -/* jogdial - really reliable ? */ -ec_read (SONY_EC_JOGB , &jog_present); -if (jog_present &SONY_EC_JOGB_MASK || force_jog) { - jog_dev =input_allocate_device (); -if (!jog_dev) { - error = -ENOMEM ; - goto err_unregister_keydev; - } - - jog_dev->name ="Sony Vaio Jogdial" ; - jog_dev->id.bustype =BUS_ISA ; - jog_dev->id.vendor =PCI_VENDOR_ID_SONY ; - - jog_dev->evbit[0 ] =BIT (EV_KEY ) |BIT (EV_REL ); - jog_dev->keybit[LONG (BTN_MOUSE )] =BIT (BTN_MIDDLE ); - jog_dev->relbit[0 ] =BIT (REL_WHEEL ); - - error =input_register_device (jog_dev); -if (error) - goto err_free_jogdev; - - spic_dev.input_jog_dev = jog_dev; - } - -return 0 ; - -err_free_jogdev: -input_free_device (jog_dev); - -err_unregister_keydev: -input_unregister_device (key_dev); -/* to avoid kref underflow below at input_free_device */ - key_dev =NULL ; - -err_free_keydev: -input_free_device (key_dev); - -err_destroy_wq: -destroy_workqueue (spic_dev.sony_pic_wq); - -err_free_kfifo: -kfifo_free (spic_dev.input_fifo); - -return error; -} - -static void sony_pic_remove_input (void ) -{ -/* flush workqueue first */ -flush_workqueue (spic_dev.sony_pic_wq); - -/* destroy input devs */ -input_unregister_device (spic_dev.input_key_dev); - spic_dev.input_key_dev =NULL ; - -if (spic_dev.input_jog_dev) { -input_unregister_device (spic_dev.input_jog_dev); - spic_dev.input_jog_dev =NULL ; - } - -destroy_workqueue (spic_dev.sony_pic_wq); -kfifo_free (spic_dev.input_fifo); -} - -/******************** -* +/* * ACPI callbacks -* -********************/ +*/ static acpi_status sony_pic_read_possible_resource (struct acpi_resource *resource,void *context) {
@@ -1409,7 +1420,7 @@ static irqreturn_t sony_pic_irq(int irq,return IRQ_HANDLED ; found: -sony_pic_report_input_event (device_event); +sony_laptop_report_input_event (device_event);acpi_bus_generate_event (spic_dev.acpi_dev,1 , device_event);return IRQ_HANDLED ;
@@ -1434,7 +1445,7 @@ static int sony_pic_remove(struct acpi_drelease_region (spic_dev.cur_ioport->io.minimum, spic_dev.cur_ioport->io.address_length); -sony_pic_remove_input (); +sony_laptop_remove_input ();list_for_each_entry_safe (io, tmp_io, &spic_dev.ioports, list) {list_del (&io->list);
@@ -1474,7 +1485,7 @@ static int sony_pic_add(struct acpi_devi }/* setup input devices and helper fifo */ - result =sony_pic_setup_input (); + result =sony_laptop_setup_input ();if (result) { printk(KERN_ERR DRV_PFX "Unabe to create input devices.\n");
@@ -1535,7 +1546,7 @@ err_release_region: spic_dev.cur_ioport->io.address_length); err_remove_input: -sony_pic_remove_input (); +sony_laptop_remove_input (); err_free_resources:list_for_each_entry_safe (io, tmp_io, &spic_dev.ioports, list) {
--
Signature · 2 lines
mattia :wq!
PATCH 6/9 additional platform attributes coming from SNY6001
In reply to a message not in the archiveRegister additional platform attributes coming from the SPIC (sonypi) driver.
--- drivers/misc/sony-laptop.c | 205 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 204 insertions(+), 1 deletion(-)
drivers/misc/sony-laptop.c +204 -1
@@ -774,7 +774,8 @@ static int sony_nc_add(struct acpi_devic } -if (sony_pf_add ()) + result =sony_pf_add (); +if (result) goto outbacklight;/* create sony_pf sysfs attributes related to the SNC device */
@@ -903,6 +904,8 @@ struct sony_pic_irq {struct sony_pic_dev {int model; +u8 camera_power; +u8 bluetooth_power;struct acpi_device *acpi_dev;struct sony_pic_irq *cur_irq;struct sony_pic_ioport *cur_ioport;
@@ -1181,6 +1184,186 @@ static u8 sony_pic_call2(u8 dev, u8 fn)return v1; } +static u8 sony_pic_call3 (u8 dev,u8 fn,u8 v) +{ +u8 v1; + +wait_on_command (inb_p (spic_dev.cur_ioport->io.minimum +4 ) &2 ,ITERATIONS_LONG ); +outb (dev, spic_dev.cur_ioport->io.minimum +4 ); +wait_on_command (inb_p (spic_dev.cur_ioport->io.minimum +4 ) &2 ,ITERATIONS_LONG ); +outb (fn, spic_dev.cur_ioport->io.minimum); +wait_on_command (inb_p (spic_dev.cur_ioport->io.minimum +4 ) &2 ,ITERATIONS_LONG ); +outb (v, spic_dev.cur_ioport->io.minimum); + v1 =inb_p (spic_dev.cur_ioport->io.minimum); +dprintk ("sony_pic_call3: 0x%.4x\n" , v1); +return v1; +} + +/* camera tests and poweron/poweroff */ +#define SONYPI_CAMERA_PICTURE 5 +#define SONYPI_CAMERA_MUTE_MASK 0x40 +#define SONYPI_CAMERA_CONTROL 0x10 +#define SONYPI_CAMERA_STATUS 7 +#define SONYPI_CAMERA_STATUS_READY 0x2 +#define SONYPI_CAMERA_STATUS_POSITION 0x4 + +static int sony_pic_camera_ready (void ) +{ +u8 v; + + v =sony_pic_call2 (0x8f ,SONYPI_CAMERA_STATUS ); +return (v !=0xff && (v &SONYPI_CAMERA_STATUS_READY )); +} + +static void sony_pic_camera_off (void ) +{ +wait_on_command (sony_pic_call3 (0x90 ,SONYPI_CAMERA_PICTURE , +SONYPI_CAMERA_MUTE_MASK ), +ITERATIONS_SHORT ); + +if (!spic_dev.camera_power) +return ; + +sony_pic_call2 (0x91 ,0 ); + spic_dev.camera_power =0 ; +} + +static void sony_pic_camera_on (void ) +{ +int i, j; + +if (spic_dev.camera_power) +return ; + +for (j =5 ; j >0 ; j--) { + +while (sony_pic_call2 (0x91 ,0x1 )) +msleep (10 ); +sony_pic_call1 (0x93 ); + +for (i =400 ; i >0 ; i--) { +if (sony_pic_camera_ready ()) +break ; +msleep (10 ); + } +if (i) +break ; + } + +if (j ==0 ) { +printk (KERN_WARNING "sonypi: failed to power on camera\n" ); +return ; + } + +wait_on_command (sony_pic_call3 (0x90 ,SONYPI_CAMERA_CONTROL , +0x5a ), +ITERATIONS_SHORT ); + + spic_dev.camera_power =1 ; +} + +static ssize_t sony_pic_camerapower_store (struct device *dev, +struct device_attribute *attr, +const char *buffer,size_t count) +{ +unsigned long value; +if (count >31 ) +return -EINVAL ; + + value =simple_strtoul (buffer,NULL ,10 ); +if (value) +sony_pic_camera_on (); +else +sony_pic_camera_off (); + +return count; +} + +static ssize_t sony_pic_camerapower_show (struct device *dev, +struct device_attribute *attr,char *buffer) +{ +return snprintf (buffer,PAGE_SIZE ,"%d\n" , spic_dev.camera_power); +} + +/* bluetooth subsystem power state */ +static void sony_pic_set_bluetoothpower (u8 state) +{ + state = !!state; +if (spic_dev.bluetooth_power == state) +return ; +sony_pic_call2 (0x96 , state); +sony_pic_call1 (0x82 ); + spic_dev.bluetooth_power = state; +} + +static ssize_t sony_pic_bluetoothpower_store (struct device *dev, +struct device_attribute *attr, +const char *buffer,size_t count) +{ +unsigned long value; +if (count >31 ) +return -EINVAL ; + + value =simple_strtoul (buffer,NULL ,10 ); +sony_pic_set_bluetoothpower (value); + +return count; +} + +static ssize_t sony_pic_bluetoothpower_show (struct device *dev, +struct device_attribute *attr,char *buffer) +{ +return snprintf (buffer,PAGE_SIZE ,"%d\n" , spic_dev.bluetooth_power); +} + +/* fan speed */ +/* FAN0 information (reverse engineered from ACPI tables) */ +#define SONY_PIC_FAN0_STATUS 0x93 +static ssize_t sony_pic_fanspeed_store (struct device *dev, +struct device_attribute *attr, +const char *buffer,size_t count) +{ +unsigned long value; +if (count >31 ) +return -EINVAL ; + + value =simple_strtoul (buffer,NULL ,10 ); +if (ec_write (SONY_PIC_FAN0_STATUS , value)) +return -EIO ; + +return count; +} + +static ssize_t sony_pic_fanspeed_show (struct device *dev, +struct device_attribute *attr,char *buffer) +{ +u8 value =0 ; +if (ec_read (SONY_PIC_FAN0_STATUS , &value)) +return -EIO ; + +return snprintf (buffer,PAGE_SIZE ,"%d\n" , value); +} + +#define SPIC_ATTR (_name, _mode) \ +struct device_attribute spic_attr_##_name = __ATTR(_name, \ + _mode, sony_pic_## _name ##_show, \ + sony_pic_## _name ##_store) + +static SPIC_ATTR(camerapower, 0644); +static SPIC_ATTR(bluetoothpower, 0644); +static SPIC_ATTR(fanspeed, 0644); + +static struct attribute *spic_attributes[] = { + &spic_attr_camerapower.attr, + &spic_attr_bluetoothpower.attr, + &spic_attr_fanspeed.attr, +NULL +}; + +static struct attribute_group spic_attribute_group = { + .attrs = spic_attributes +}; +/* * ACPI callbacks */
@@ -1447,6 +1630,10 @@ static int sony_pic_remove(struct acpi_dsony_laptop_remove_input (); +/* pf attrs */ +sysfs_remove_group (&sony_pf_device->dev.kobj, &spic_attribute_group); +sony_pf_remove (); +list_for_each_entry_safe (io, tmp_io, &spic_dev.ioports, list) {list_del (&io->list);kfree (io);
@@ -1536,8 +1723,24 @@ static int sony_pic_add(struct acpi_devi goto err_free_irq; } + spic_dev.bluetooth_power =-1 ; +/* create device attributes */ + result =sony_pf_add (); +if (result) + goto err_disable_device; + + result =sysfs_create_group (&sony_pf_device->dev.kobj, &spic_attribute_group); +if (result) + goto err_remove_pf; +return 0 ; +err_remove_pf: +sony_pf_remove (); + +err_disable_device: +sony_pic_disable (device); + err_free_irq:free_irq (spic_dev.cur_irq->irq.interrupts[0 ], &spic_dev);
--
Signature · 2 lines
mattia :wq!
PATCH 7/9 sanitize printks
In reply to a message not in the archiveUnify printks to resemble a unique driver.
--- drivers/misc/sony-laptop.c | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-)
drivers/misc/sony-laptop.c +19 -21
@@ -64,20 +64,19 @@#include <linux/sonypi.h> #define DRV_PFX "sony-laptop: " -#define LOG_PFX KERN_WARNING DRV_PFX #define dprintk(msg...) do { \ - if (debug) printk(LOG_PFX msg); \ + if (debug) printk(KERN_WARNING DRV_PFX msg); \ } while (0)#define SONY_LAPTOP_DRIVER_VERSION "0.5"#define SONY_NC_CLASS "sony-nc"#define SONY_NC_HID "SNY5001" -#define SONY_NC_DRIVER_NAME "Sony Notebook Control" +#define SONY_NC_DRIVER_NAME "Sony Notebook Control Driver"#define SONY_PIC_CLASS "sony-pic"#define SONY_PIC_HID "SNY6001" -#define SONY_PIC_DRIVER_NAME "Sony Programmable IO Control" +#define SONY_PIC_DRIVER_NAME "Sony Programmable IO Control Driver"MODULE_AUTHOR ("Stelian Pop, Mattia Dongili" );MODULE_DESCRIPTION ("Sony laptop extras driver (SPIC and SNC ACPI device)" );
@@ -518,7 +517,7 @@ static int acpi_callgetfunc(acpi_handlereturn 0 ; } -printk (LOG_PFX "acpi_callreadfunc failed\n" ); + printk(KERN_WARNING DRV_PFX "acpi_callreadfunc failed\n");return -1 ; }
@@ -544,7 +543,7 @@ static int acpi_callsetfunc(acpi_handleif (status ==AE_OK ) {if (result !=NULL ) {if (out_obj.type !=ACPI_TYPE_INTEGER ) { -printk (LOG_PFX "acpi_evaluate_object bad " + printk(KERN_WARNING DRV_PFX "acpi_evaluate_object bad " "return type\n");return -1 ; }
@@ -553,7 +552,7 @@ static int acpi_callsetfunc(acpi_handlereturn 0 ; } -printk (LOG_PFX "acpi_evaluate_object failed\n" ); + printk(KERN_WARNING DRV_PFX "acpi_evaluate_object failed\n");return -1 ; }
@@ -689,7 +688,7 @@ static acpi_status sony_walk_callback(ac 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, + printk(KERN_WARNING DRV_PFX "method: name: %4.4s, args %X\n", node->name.ascii, (u32) operand->method.param_count);return AE_OK ;
@@ -724,6 +723,9 @@ static int sony_nc_add(struct acpi_devicacpi_handle handle;struct sony_nc_value *item; + printk(KERN_INFO DRV_PFX "%s v%s.\n", + SONY_NC_DRIVER_NAME, SONY_LAPTOP_DRIVER_VERSION); + sony_nc_acpi_device = device;strcpy (acpi_device_class (device),"sony/hotkey" );
@@ -733,7 +735,7 @@ static int sony_nc_add(struct acpi_devic status =acpi_walk_namespace (ACPI_TYPE_METHOD , sony_nc_acpi_handle,1 , sony_walk_callback,NULL ,NULL );if (ACPI_FAILURE (status)) { -printk (LOG_PFX "unable to walk acpi resources\n" ); + printk(KERN_WARNING DRV_PFX "unable to walk acpi resources\n"); result = -ENODEV ; goto outwalk; }
@@ -751,7 +753,7 @@ static int sony_nc_add(struct acpi_devicACPI_DEVICE_NOTIFY , sony_acpi_notify, NULL);if (ACPI_FAILURE (status)) { -printk (LOG_PFX "unable to install notify handler\n" ); + printk(KERN_WARNING DRV_PFX "unable to install notify handler\n"); result = -ENODEV ; goto outinput; }
@@ -762,7 +764,7 @@ static int sony_nc_add(struct acpi_devic &sony_backlight_ops);if (IS_ERR (sony_backlight_device)) { -printk (LOG_PFX "unable to register backlight device\n" ); + printk(KERN_WARNING DRV_PFX "unable to register backlight device\n"); sony_backlight_device =NULL ; }else { sony_backlight_device->props.brightness =
@@ -817,8 +819,6 @@ static int sony_nc_add(struct acpi_devic } } - printk(KERN_INFO SONY_NC_DRIVER_NAME " successfully installed\n"); -return 0 ; out_sysfs:
@@ -835,7 +835,7 @@ static int sony_nc_add(struct acpi_devicACPI_DEVICE_NOTIFY , sony_acpi_notify);if (ACPI_FAILURE (status)) -printk (LOG_PFX "unable to remove notify handler\n" ); + printk(KERN_WARNING DRV_PFX "unable to remove notify handler\n"); outinput:sony_laptop_remove_input ();
@@ -858,7 +858,7 @@ static int sony_nc_remove(struct acpi_deACPI_DEVICE_NOTIFY , sony_acpi_notify);if (ACPI_FAILURE (status)) -printk (LOG_PFX "unable to remove notify handler\n" ); + printk(KERN_WARNING DRV_PFX "unable to remove notify handler\n");for (item = sony_nc_values; item->name; ++item) {device_remove_file (&sony_pf_device->dev, &item->devattr);
@@ -866,8 +866,7 @@ static int sony_nc_remove(struct acpi_desony_pf_remove ();sony_laptop_remove_input (); - - printk(KERN_INFO SONY_NC_DRIVER_NAME " successfully removed\n"); +dprintk (SONY_NC_DRIVER_NAME " removed.\n" );return 0 ; }
@@ -1645,7 +1644,7 @@ static int sony_pic_remove(struct acpi_d spic_dev.cur_ioport =NULL ; spic_dev.cur_irq =NULL ; -dprintk ("removed.\n" ); +dprintk (SONY_PIC_DRIVER_NAME " removed.\n" );return 0 ; }
@@ -1655,9 +1654,8 @@ static int sony_pic_add(struct acpi_devistruct sony_pic_ioport *io, *tmp_io;struct sony_pic_irq *irq, *tmp_irq; - printk(KERN_INFO DRV_PFX -"Sony Programmable I/O Controller Driver v%s.\n" , - SONY_LAPTOP_DRIVER_VERSION); + printk(KERN_INFO DRV_PFX "%s v%s.\n", + SONY_PIC_DRIVER_NAME, SONY_LAPTOP_DRIVER_VERSION); spic_dev.acpi_dev = device;strcpy (acpi_device_class (device),"sony/hotkey" );
--
Signature · 2 lines
mattia :wq!
PATCH 8/9 update documentation and Kconfig help
In reply to a message not in the archive--- Documentation/sony-laptop.txt | 25 ++++++++++++++++++------- drivers/misc/Kconfig | 9 ++++----- 2 files changed, 22 insertions(+), 12 deletions(-)
Documentation/sony-laptop.txt +18 -7
@@ -3,12 +3,18 @@ Sony Notebook Control Driver (SNC) Readm Copyright (C) 2004- 2005 Stelian Pop <[email protected]> Copyright (C) 2007 Mattia Dongili <[email protected]> -This mini-driver drives the SNC device present in the ACPI BIOS of -the Sony Vaio laptops. +This mini-driver drives the SNC and SPIC device present in the ACPI BIOS of the +Sony Vaio laptops. This driver mixes both devices functions under the same +(hopefully consistent) interface. This also means that the sonypi driver is +obsoleted by sony-laptop now. -It gives access to some extra laptop functionalities. In its current -form, this driver let the user set or query the screen brightness -through the backlight subsystem and remove/apply power to some devices. +Fn keys (hotkeys): +------------------ +Some models report hotkeys through the SNC or SPIC devices, such events are +reported both through the ACPI subsystem as acpi events and through the INPUT +subsystem. See the logs of acpid or /proc/acpi/event and +/proc/bus/input/devices to find out what those events are and which input +devices are created by the driver. Backlight control: ------------------
@@ -39,6 +45,8 @@ The files are: audiopower power on/off the internal sound card lanpower power on/off the internal ethernet card (only in debug mode) + bluetoothpower power on/off the internal bluetooth device + fanspeed get/set the fan speed Note that some files may be missing if they are not supported by your particular laptop model.
@@ -76,9 +84,9 @@ The sony-laptop driver creates, for some current ones found on several Vaio models), an entry under /sys/devices/platform/sony-laptop, just like the 'cdpower' 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 +further editing the source (see the 'sony_nc_values' table, and add a new entry to this table with your get/set method names using the -HANDLE_NAMES macro). +SNC_HANDLE_NAMES macro). Your mission, should you accept it, is to try finding out what those entries are for, by reading/writing random values from/to those
@@ -87,6 +95,9 @@ files and find out what is the impact on Should you find anything interesting, please report it back to me, I will not disavow all knowledge of your actions :) +See also http://www.linux.it/~malattia/wiki/index.php/Sony_drivers for other +useful info. + Bugs/Limitations: -----------------
drivers/misc/Kconfig +4 -5
@@ -112,12 +112,11 @@ config SONY_LAPTOP depends on X86 && ACPI select BACKLIGHT_CLASS_DEVICE ---help--- - This mini-driver drives the SNC device present in the ACPI BIOS of - the Sony Vaio laptops. + This mini-driver drives the SNC and SPIC devices present in the ACPI + BIOS of the Sony Vaio laptops. - It gives access to some extra laptop functionalities. In its current - form, this driver let the user set or query the screen brightness - through the backlight subsystem and remove/apply power to some + It gives access to some extra laptop functionalities like Bluetooth, + screen brightness control, Fn keys and allows powering on/off some devices. Read <file:Documentation/sony-laptop.txt> for more information.
--
Signature · 2 lines
mattia :wq!
PATCH 9/9 sonypi backward compatibility code
In reply to a message not in the archiveCompatibility code to allow old sonypi bound userspace apps to still work.
--- drivers/misc/Kconfig | 6 drivers/misc/sony-laptop.c | 332 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 335 insertions(+), 3 deletions(-)
drivers/misc/sony-laptop.c +329 -3
@@ -62,6 +62,10 @@#include <acpi/acpi_bus.h> #include <asm/uaccess.h> #include <linux/sonypi.h> +#ifdef CONFIG_SONY_LAPTOP_OLD +#include <linux/poll.h> +#include <linux/miscdevice.h> +#endif #define DRV_PFX "sony-laptop: " #define dprintk(msg...) do { \
@@ -96,13 +100,21 @@ MODULE_PARM_DESC(no_spic,static int compat;/* = 0 */ module_param (compat, int,0444 );MODULE_PARM_DESC (compat, -"set this if you want to enable backward compatibility mode for SPIC" ); +"set this if you want to enable backward compatibility mode" );static unsigned long mask =0xffffffff ;module_param (mask, ulong,0644 );MODULE_PARM_DESC (mask,"set this to the mask of event you want to enable (see doc)" ); +#ifdef CONFIG_SONY_LAPTOP_OLD +static int minor =-1 ; +module_param (minor, int,0 ); +MODULE_PARM_DESC (minor, +"minor number of the misc device for the SPIC compatibility code, " +"default is -1 (automatic)" ); +#endif +/*********** Input Devices ***********/ #define SONY_LAPTOP_BUF_SIZE 128
@@ -1318,6 +1330,16 @@ static ssize_t sony_pic_bluetoothpower_s/* fan speed */ /* FAN0 information (reverse engineered from ACPI tables) */ #define SONY_PIC_FAN0_STATUS 0x93 +static int sony_pic_set_fanspeed (unsigned long value) +{ +return ec_write (SONY_PIC_FAN0_STATUS , value); +} + +static int sony_pic_get_fanspeed (u8 *value) +{ +return ec_read (SONY_PIC_FAN0_STATUS , value); +} +static ssize_t sony_pic_fanspeed_store (struct device *dev,struct device_attribute *attr,const char *buffer,size_t count)
@@ -1327,7 +1349,7 @@ static ssize_t sony_pic_fanspeed_store(sreturn -EINVAL ; value =simple_strtoul (buffer,NULL ,10 ); -if (ec_write (SONY_PIC_FAN0_STATUS , value)) +if (sony_pic_set_fanspeed (value))return -EIO ;return count;
@@ -1337,7 +1359,7 @@ static ssize_t sony_pic_fanspeed_show(st struct device_attribute *attr, char *buffer) { u8 value = 0; -if (ec_read (SONY_PIC_FAN0_STATUS , &value)) +if (sony_pic_get_fanspeed (&value))return -EIO ;return snprintf (buffer,PAGE_SIZE ,"%d\n" , value);
@@ -1363,6 +1385,304 @@ static struct attribute_group spic_attri .attrs = spic_attributes }; +/******** SONYPI compatibility **********/ +#ifdef CONFIG_SONY_LAPTOP_OLD + +/* battery / brightness / temperature addresses */ +#define SONYPI_BAT_FLAGS 0x81 +#define SONYPI_LCD_LIGHT 0x96 +#define SONYPI_BAT1_PCTRM 0xa0 +#define SONYPI_BAT1_LEFT 0xa2 +#define SONYPI_BAT1_MAXRT 0xa4 +#define SONYPI_BAT2_PCTRM 0xa8 +#define SONYPI_BAT2_LEFT 0xaa +#define SONYPI_BAT2_MAXRT 0xac +#define SONYPI_BAT1_MAXTK 0xb0 +#define SONYPI_BAT1_FULL 0xb2 +#define SONYPI_BAT2_MAXTK 0xb8 +#define SONYPI_BAT2_FULL 0xba +#define SONYPI_TEMP_STATUS 0xC1 + +struct sonypi_compat_s { +struct fasync_struct *fifo_async; +struct kfifo *fifo; +spinlock_t fifo_lock; +wait_queue_head_t fifo_proc_list; +atomic_t open_count; +}; +static struct sonypi_compat_s sonypi_compat = { + .open_count =ATOMIC_INIT (0 ), +}; + +static int sonypi_misc_fasync (int fd,struct file *filp,int on) +{ +int retval; + + retval =fasync_helper (fd, filp, on, &sonypi_compat.fifo_async); +if (retval <0 ) +return retval; +return 0 ; +} + +static int sonypi_misc_release (struct inode *inode,struct file *file) +{ +sonypi_misc_fasync (-1 , file,0 ); +atomic_dec (&sonypi_compat.open_count); +return 0 ; +} + +static int sonypi_misc_open (struct inode *inode,struct file *file) +{ +/* Flush input queue on first open */ +if (atomic_inc_return (&sonypi_compat.open_count) ==1 ) +kfifo_reset (sonypi_compat.fifo); +return 0 ; +} + +static ssize_t sonypi_misc_read (struct file *file,char __user *buf, +size_t count,loff_t *pos) +{ +ssize_t ret; +unsigned char c; + +if ((kfifo_len (sonypi_compat.fifo) ==0 ) && + (file->f_flags &O_NONBLOCK )) +return -EAGAIN ; + + ret =wait_event_interruptible (sonypi_compat.fifo_proc_list, +kfifo_len (sonypi_compat.fifo) !=0 ); +if (ret) +return ret; + +while (ret < count && + (kfifo_get (sonypi_compat.fifo, &c,sizeof (c)) ==sizeof (c))) { +if (put_user (c, buf++)) +return -EFAULT ; + ret++; + } + +if (ret >0 ) { +struct inode *inode = file->f_path.dentry->d_inode; + inode->i_atime =current_fs_time (inode->i_sb); + } + +return ret; +} + +static unsigned int sonypi_misc_poll (struct file *file,poll_table *wait) +{ +poll_wait (file, &sonypi_compat.fifo_proc_list, wait); +if (kfifo_len (sonypi_compat.fifo)) +return POLLIN |POLLRDNORM ; +return 0 ; +} + +static int ec_read16 (u8 addr,u16 *value) +{ +u8 val_lb, val_hb; +if (ec_read (addr, &val_lb)) +return -1 ; +if (ec_read (addr +1 , &val_hb)) +return -1 ; + *value = val_lb | (val_hb <<8 ); +return 0 ; +} + +static int sonypi_misc_ioctl (struct inode *ip,struct file *fp, +unsigned int cmd,unsigned long arg) +{ +int ret =0 ; +void __user *argp = (void __user *)arg; +u8 val8; +u16 val16; +int value; + +/*down(&sonypi_device.lock);*/ +switch (cmd) { +case SONYPI_IOCGBRT : +if (sony_backlight_device ==NULL ) { + ret = -EIO ; +break ; + } +if (acpi_callgetfunc (sony_nc_acpi_handle,"GBRT" , &value)) { + ret = -EIO ; +break ; + } + val8 = ((value &0xff ) -1 ) <<5 ; +if (copy_to_user (argp, &val8,sizeof (val8))) + ret = -EFAULT ; +break ; +case SONYPI_IOCSBRT : +if (sony_backlight_device ==NULL ) { + ret = -EIO ; +break ; + } +if (copy_from_user (&val8, argp,sizeof (val8))) { + ret = -EFAULT ; +break ; + } +if (acpi_callsetfunc (sony_nc_acpi_handle,"SBRT" , + (val8 >>5 ) +1 ,NULL )) { + ret = -EIO ; +break ; + } +/* sync the backlight device status */ + sony_backlight_device->props.brightness = +sony_backlight_get_brightness (sony_backlight_device); +break ; +case SONYPI_IOCGBAT1CAP : +if (ec_read16 (SONYPI_BAT1_FULL , &val16)) { + ret = -EIO ; +break ; + } +if (copy_to_user (argp, &val16,sizeof (val16))) + ret = -EFAULT ; +break ; +case SONYPI_IOCGBAT1REM : +if (ec_read16 (SONYPI_BAT1_LEFT , &val16)) { + ret = -EIO ; +break ; + } +if (copy_to_user (argp, &val16,sizeof (val16))) + ret = -EFAULT ; +break ; +case SONYPI_IOCGBAT2CAP : +if (ec_read16 (SONYPI_BAT2_FULL , &val16)) { + ret = -EIO ; +break ; + } +if (copy_to_user (argp, &val16,sizeof (val16))) + ret = -EFAULT ; +break ; +case SONYPI_IOCGBAT2REM : +if (ec_read16 (SONYPI_BAT2_LEFT , &val16)) { + ret = -EIO ; +break ; + } +if (copy_to_user (argp, &val16,sizeof (val16))) + ret = -EFAULT ; +break ; +case SONYPI_IOCGBATFLAGS : +if (ec_read (SONYPI_BAT_FLAGS , &val8)) { + ret = -EIO ; +break ; + } + val8 &=0x07 ; +if (copy_to_user (argp, &val8,sizeof (val8))) + ret = -EFAULT ; +break ; +case SONYPI_IOCGBLUE : + val8 = spic_dev.bluetooth_power; +if (copy_to_user (argp, &val8,sizeof (val8))) + ret = -EFAULT ; +break ; +case SONYPI_IOCSBLUE : +if (copy_from_user (&val8, argp,sizeof (val8))) { + ret = -EFAULT ; +break ; + } +sony_pic_set_bluetoothpower (val8); +break ; +/* FAN Controls */ +case SONYPI_IOCGFAN : +if (sony_pic_get_fanspeed (&val8)) { + ret = -EIO ; +break ; + } +if (copy_to_user (argp, &val8,sizeof (val8))) + ret = -EFAULT ; +break ; +case SONYPI_IOCSFAN : +if (copy_from_user (&val8, argp,sizeof (val8))) { + ret = -EFAULT ; +break ; + } +if (sony_pic_set_fanspeed (val8)) + ret = -EIO ; +break ; +/* GET Temperature (useful under APM) */ +case SONYPI_IOCGTEMP : +if (ec_read (SONYPI_TEMP_STATUS , &val8)) { + ret = -EIO ; +break ; + } +if (copy_to_user (argp, &val8,sizeof (val8))) + ret = -EFAULT ; +break ; +default : + ret = -EINVAL ; + } +/*up(&sonypi_device.lock);*/ +return ret; +} + +static const struct file_operations sonypi_misc_fops = { + .owner =THIS_MODULE , + .read = sonypi_misc_read, + .poll = sonypi_misc_poll, + .open = sonypi_misc_open, + .release = sonypi_misc_release, + .fasync = sonypi_misc_fasync, + .ioctl = sonypi_misc_ioctl, +}; + +static struct miscdevice sonypi_misc_device = { + .minor =MISC_DYNAMIC_MINOR , + .name ="sonypi" , + .fops = &sonypi_misc_fops, +}; + +static void sonypi_compat_report_event (u8 event) +{ +kfifo_put (sonypi_compat.fifo, (unsigned char *)&event,sizeof (event)); +kill_fasync (&sonypi_compat.fifo_async,SIGIO ,POLL_IN ); +wake_up_interruptible (&sonypi_compat.fifo_proc_list); +} + +static int sonypi_compat_init (void ) +{ +int error; + +spin_lock_init (&sonypi_compat.fifo_lock); + sonypi_compat.fifo =kfifo_alloc (SONY_LAPTOP_BUF_SIZE ,GFP_KERNEL , + &sonypi_compat.fifo_lock); +if (IS_ERR (sonypi_compat.fifo)) { + printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n"); +return PTR_ERR (sonypi_compat.fifo); + } + +init_waitqueue_head (&sonypi_compat.fifo_proc_list); +/*init_MUTEX(&sonypi_device.lock);*/ + +if (minor !=-1 ) + sonypi_misc_device.minor = minor; + error =misc_register (&sonypi_misc_device); +if (error) { + printk(KERN_ERR DRV_PFX "misc_register failed\n"); + goto err_free_kfifo; + } +if (minor ==-1 ) +printk (KERN_INFO "sonypi: device allocated minor is %d\n" , + sonypi_misc_device.minor); + +return 0 ; + +err_free_kfifo: +kfifo_free (sonypi_compat.fifo); +return error; +} + +static void sonypi_compat_exit (void ) +{ +misc_deregister (&sonypi_misc_device); +kfifo_free (sonypi_compat.fifo); +} +#else +static int sonypi_compat_init (void ) {return 0 ; } +static void sonypi_compat_exit (void ) { } +static void sonypi_compat_report_event (u8 event) { } +#endif /* CONFIG_SONY_LAPTOP_OLD */ +/* * ACPI callbacks */
@@ -1604,6 +1924,7 @@ static irqreturn_t sony_pic_irq(int irq, found:sony_laptop_report_input_event (device_event);acpi_bus_generate_event (spic_dev.acpi_dev,1 , device_event); +sonypi_compat_report_event (device_event);return IRQ_HANDLED ; }
@@ -1618,6 +1939,8 @@ static int sony_pic_remove(struct acpi_dstruct sony_pic_ioport *io, *tmp_io;struct sony_pic_irq *irq, *tmp_irq; +sonypi_compat_exit (); +if (sony_pic_disable (device)) { printk(KERN_ERR DRV_PFX "Couldn't disable device.\n");return -ENXIO ;
@@ -1731,6 +2054,9 @@ static int sony_pic_add(struct acpi_deviif (result) goto err_remove_pf; +if (sonypi_compat_init ()) + goto err_remove_pf; +return 0 ; err_remove_pf:
drivers/misc/Kconfig +6 -0
@@ -121,6 +121,12 @@ config SONY_LAPTOP Read <file:Documentation/sony-laptop.txt> for more information. +config SONY_LAPTOP_OLD + bool "Sonypi compatibility" + depends on SONY_LAPTOP + ---help--- + Build the sonypi driver compatibility code into the sony-laptop driver. + config THINKPAD_ACPI tristate "ThinkPad ACPI Laptop Extras" depends on X86 && ACPI
--
Signature · 2 lines
mattia :wq!
Len Brown
reviewerRe: [patch 0/9] [RFC] sonypi ACPI reimplementation (resend 3)
In reply to a message not in the archiveQuoted 11 lines · On Monday 09 April 2007 04:19, [email protected] wrote:
[Resend 3: hopefully this time it will make to the list and the intended recipients]
The following patch series is the state of the art of my work toward reimplementing sonypi into sony-laptop. Most patches are mostly cosmetic to try to obtain a decent namespace separation between the used subsystems and the drivers driving the two sony devices (SNC and SPIC). If suitable it would be nice to start applying to acpi-test so that akpm gets them in -mm (update: it's already in .21-rc6-mm1).
Len, if you prefer a big large patch or a different series, just ask.
This is fine, thanks.
Quoted 3 lines
The most interesting patches are probably 0004, 0006 and 0009. Andrew, the 9th patch is now really against acpi-test (I think the
Kconfighunk didn't apply correclty).
BTW. I check-in on top of Linus' tree, not on top of acpi-test. Then i merge into acpi-test. So in the future, you could just as well base on Linus' tree and let me deal with the conflicts within acpi-test. fine with me either way, just mention where the base is like you have.
Quoted 9 lines
0001-Remove-ACPI-references-from-variable-and-function-names.patch 0002-prepare-pfdriver-for-multiple-users.patch 0003-introduce-debug-macros.patch 0004-add-sny6001-device-handling-from-sonypi.patch 0005-unify-input-subsystem-event-fwd.patch 0006-add-SNY6001-platform-attributes.patch 0007-sanitize-printk-logs.patch 0008-update-documentation.patch 0009-add-sonypi-compat-code.patch
Quoted 8 lines
--- Documentation/sony-laptop.txt | 25 drivers/misc/Kconfig | 15 drivers/misc/sony-laptop.c | 2019 +++++++++++++++++++++++++++++++++++++----- 3 files changed, 1842 insertions(+), 217 deletions(-)
SONY_LAPTOP_OLD
There is probably a better name for this -- like SONY_PI_COMPATIBILITY or something.
What about CONFIG_SONYPI? -- should it now depend on this driver not being included?
SONYPI depends on !64BIT -- is that invalid, or perhaps you only need the compatibility stuff only in 32-bit mode?
applied to acpi-test.
It would be great if you can get some test feedback for the sonypi-era features to make sure that the code moved into the new driver works as well as the old sonypi.
thanks,
-Len
Re: [patch 0/9] [RFC] sonypi ACPI reimplementation (resend 3)
Quoted 1 line · Len Brown
On Monday 09 April 2007 04:19, [email protected] wrote:
...
Quoted 3 lines
Quoted 1 line
SONY_LAPTOP_OLDThere is probably a better name for this -- like
SONY_PI_COMPATIBILITYor something.
ok, will change asap, I have a couple more patches here that I'll send in soon.
Quoted 1 line
What about
CONFIG_SONYPI? -- should it now depend on this driver not being included?
So, all in all I'd like to obsolete sonypi as soon as possible to get more feedback but the 2 drivers can still live together for a while.
When you try to load both 2 things can happen:
- if you load sonypi first it will steal part of sony-laptop functionalities (the rewrite stuff for the SPIC acpi device)
- if you load sony-laptop first sonypi will bomb out with kobject_add failed for sonypi with -EEXIST
on misc_register(). sony-laptop also offers a no_spic option to not drive the SPIC device.
The only function that sony-laptop doesn't offer is the motion eye camera stuff, which the meye driver also depend on and which makes sonypi useful at least for a couple of vaio models. I can add it to sony-laptop[1] but I can't test.
I should probably add some printks in sonypi to suggest moving towards sony-laptop and try to detect if the known ioports are being used by sony-laptop to better handle the sonypi load failure (see below).
[1]: there are some bits in the patches I submitted but I'll remove them with the next submission.
Quoted 2 lines
SONYPI depends on !64BIT -- is that invalid, or perhaps you only need the compatibility stuff only in 32-bit mode?
it's invalid. I'd rather avoid changing sonypi to work also on 64bit, for 64bit vaios the new sony-laptop should be good enough.
Quoted 1 line
applied to acpi-test.
Thanks!
Quoted 2 lines
It would be great if you can get some test feedback for the sonypi-era features to make sure that the code moved into the new driver works as well as the old sonypi.
I already asked a couple of users to try it and it seems to work well for them (and for their purposes). I guess obsoleting sonypi may increase the reports number ;)
Signature · 2 lines
mattia :wq!
Re: [patch 0/9] [RFC] sonypi ACPI reimplementation (resend 3)
Quoted 4 lines · Mattia Dongili
The only function that sony-laptop doesn't offer is the motion eye camera stuff, which the meye driver also depend on and which makes sonypi useful at least for a couple of vaio models. I can add it to sony-laptop[1] but I can't test.
The meye stuff is quite trivial, I think you can try putting it in and let the users test...
Quoted 3 lines
I should probably add some printks in sonypi to suggest moving towards sony-laptop and try to detect if the known ioports are being used by sony-laptop to better handle the sonypi load failure (see below).
This would be a good idea. Maybe let it printk a pointer to the sonypi wiki.
I have also put links to the new wiki on my sonypi web pages, this should help the users find the relevant information.
Signature · 6 lines
Stelian Pop <[email protected]> - To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html