* [PATCH 1/8] sony-laptop: add some debug printk useful for bug reports
2011-02-19 2:52 [0/8] sony-laptop for 2.6.39 Mattia Dongili
@ 2011-02-19 2:52 ` Mattia Dongili
2011-02-19 2:52 ` [PATCH 2/8] sony-laptop: documentation updates Mattia Dongili
` (7 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Mattia Dongili @ 2011-02-19 2:52 UTC (permalink / raw)
To: Matthew Garrett; +Cc: platform-driver-x86, Mattia Dongili
Signed-off-by: Mattia Dongili <malattia@linux.it>
---
drivers/platform/x86/sony-laptop.c | 14 +++++++++++---
1 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index 5e83370..3aaa92e 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -733,22 +733,30 @@ static int sony_find_snc_handle(int handle)
for (i = 0x20; i < 0x30; i++) {
acpi_callsetfunc(sony_nc_acpi_handle, "SN00", i, &result);
- if (result == handle)
+ if (result == handle) {
+ dprintk("found handle 0x%.4x (offset: 0x%.2x)\n",
+ handle, i - 0x20);
return i-0x20;
+ }
}
+ dprintk("handle 0x%.4x not found\n", handle);
return -1;
}
static int sony_call_snc_handle(int handle, int argument, int *result)
{
+ int ret = 0;
int offset = sony_find_snc_handle(handle);
if (offset < 0)
return -1;
- return acpi_callsetfunc(sony_nc_acpi_handle, "SN07", offset | argument,
- result);
+ ret = acpi_callsetfunc(sony_nc_acpi_handle, "SN07", offset | argument,
+ result);
+ dprintk("called SN07 with 0x%.4x (result: 0x%.4x)\n", offset | argument,
+ *result);
+ return ret;
}
/*
--
1.7.2.3
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH 2/8] sony-laptop: documentation updates
2011-02-19 2:52 [0/8] sony-laptop for 2.6.39 Mattia Dongili
2011-02-19 2:52 ` [PATCH 1/8] sony-laptop: add some debug printk useful for bug reports Mattia Dongili
@ 2011-02-19 2:52 ` Mattia Dongili
2011-02-19 2:52 ` [PATCH 3/8] sony-laptop: ignore hard switch rfkill events (SPIC) Mattia Dongili
` (6 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Mattia Dongili @ 2011-02-19 2:52 UTC (permalink / raw)
To: Matthew Garrett; +Cc: platform-driver-x86, Mattia Dongili
Signed-off-by: Mattia Dongili <malattia@linux.it>
---
Documentation/laptops/sony-laptop.txt | 37 ++++++++++++++++++++++++++------
1 files changed, 30 insertions(+), 7 deletions(-)
diff --git a/Documentation/laptops/sony-laptop.txt b/Documentation/laptops/sony-laptop.txt
index 23ce7d3..2bd4e82 100644
--- a/Documentation/laptops/sony-laptop.txt
+++ b/Documentation/laptops/sony-laptop.txt
@@ -14,7 +14,8 @@ 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.
+devices are created by the driver. Additionally, loading the driver with the
+debug option will report all events in the kernel log.
Backlight control:
------------------
@@ -64,6 +65,16 @@ powers off the sound card,
# echo "1" > /sys/devices/platform/sony-laptop/audiopower
powers on the sound card.
+
+RFkill control:
+---------------
+More recent Vaio models expose a consistent set of ACPI methods to
+control radio frequency emitting devices. If you are a lucky owner of
+such a laptop you will find the necessary rfkill devices under
+/sys/class/rfkill. Check those starting with sony-* in
+ # grep . /sys/class/rfkill/*/{state,name}
+
+
Development:
------------
@@ -75,8 +86,21 @@ pass the option 'debug=1'.
REPEAT: DON'T DO THIS IF YOU DON'T LIKE RISKY BUSINESS.
In your kernel logs you will find the list of all ACPI methods
-the SNC device has on your laptop. You can see the GCDP/GCDP methods
-used to pwer on/off the CD drive, but there are others.
+the SNC device has on your laptop.
+
+* For new models you will see a long list of meaningless method names,
+reading the DSDT table source should reveal that:
+(1) the SNC device uses an internal capability lookup table
+(2) SN00 is used to find values in the lookup table
+(3) SN06 and SN07 are used to call into the real methods based on
+ offsets you can obtain iterating the table using SN00
+(4) SN02 used to enable events.
+Some values in the capability lookup table are more or less known, see
+the code for all sony_call_snc_handle calls, others are more obscure.
+
+* For old models you can see the GCDP/GCDP methods used to pwer on/off
+the CD drive, but there are others and they are usually different from
+model to model.
I HAVE NO IDEA WHAT THOSE METHODS DO.
@@ -108,9 +132,8 @@ Bugs/Limitations:
laptop, including permanent damage.
* The sony-laptop and sonypi drivers do not interact at all. In the
- future, sonypi could use sony-laptop to do (part of) its business.
+ future, sonypi will be removed and replaced by sony-laptop.
* spicctrl, which is the userspace tool used to communicate with the
- sonypi driver (through /dev/sonypi) does not try to use the
- sony-laptop driver. In the future, spicctrl could try sonypi first,
- and if it isn't present, try sony-laptop instead.
+ sonypi driver (through /dev/sonypi) is deprecated as well since all
+ its features are now available under the sysfs tree via sony-laptop.
--
1.7.2.3
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH 3/8] sony-laptop: ignore hard switch rfkill events (SPIC)
2011-02-19 2:52 [0/8] sony-laptop for 2.6.39 Mattia Dongili
2011-02-19 2:52 ` [PATCH 1/8] sony-laptop: add some debug printk useful for bug reports Mattia Dongili
2011-02-19 2:52 ` [PATCH 2/8] sony-laptop: documentation updates Mattia Dongili
@ 2011-02-19 2:52 ` Mattia Dongili
2011-02-19 3:06 ` Matthew Garrett
2011-02-19 2:52 ` [PATCH 4/8] sony-laptop: use pr_<level> for messages Mattia Dongili
` (5 subsequent siblings)
8 siblings, 1 reply; 15+ messages in thread
From: Mattia Dongili @ 2011-02-19 2:52 UTC (permalink / raw)
To: Matthew Garrett; +Cc: platform-driver-x86, Mattia Dongili
There is not much use for these events in userspace and handling the
events themselves seems to get in the way of the actual activation of
the rf devices. The SNC device doesn't expose them already.
https://bugzilla.kernel.org/show_bug.cgi?id=15303
Signed-off-by: Mattia Dongili <malattia@linux.it>
---
drivers/platform/x86/sony-laptop.c | 8 +++++---
include/linux/sonypi.h | 1 +
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index 3aaa92e..ad7c496 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -1591,8 +1591,8 @@ static struct sonypi_event sonypi_blueev[] = {
/* The set of possible wireless events */
static struct sonypi_event sonypi_wlessev[] = {
- { 0x59, SONYPI_EVENT_WIRELESS_ON },
- { 0x5a, SONYPI_EVENT_WIRELESS_OFF },
+ { 0x59, SONYPI_EVENT_IGNORE },
+ { 0x5a, SONYPI_EVENT_IGNORE },
{ 0, 0 }
};
@@ -2732,6 +2732,9 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id)
if (ev == dev->event_types[i].events[j].data) {
device_event =
dev->event_types[i].events[j].event;
+ /* some events may require ignoring */
+ if (!device_event)
+ return IRQ_HANDLED;
goto found;
}
}
@@ -2751,7 +2754,6 @@ found:
sony_laptop_report_input_event(device_event);
acpi_bus_generate_proc_event(dev->acpi_dev, 1, device_event);
sonypi_compat_report_event(device_event);
-
return IRQ_HANDLED;
}
diff --git a/include/linux/sonypi.h b/include/linux/sonypi.h
index 0e6dc38..c0f87da 100644
--- a/include/linux/sonypi.h
+++ b/include/linux/sonypi.h
@@ -40,6 +40,7 @@
/* events the user application reading /dev/sonypi can use */
+#define SONYPI_EVENT_IGNORE 0
#define SONYPI_EVENT_JOGDIAL_DOWN 1
#define SONYPI_EVENT_JOGDIAL_UP 2
#define SONYPI_EVENT_JOGDIAL_DOWN_PRESSED 3
--
1.7.2.3
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH 3/8] sony-laptop: ignore hard switch rfkill events (SPIC)
2011-02-19 2:52 ` [PATCH 3/8] sony-laptop: ignore hard switch rfkill events (SPIC) Mattia Dongili
@ 2011-02-19 3:06 ` Matthew Garrett
2011-02-19 12:46 ` Mattia Dongili
0 siblings, 1 reply; 15+ messages in thread
From: Matthew Garrett @ 2011-02-19 3:06 UTC (permalink / raw)
To: Mattia Dongili; +Cc: platform-driver-x86
Do you possibly want to catch these and make sure the kernel rfkill
state matches the hardware?
--
Matthew Garrett | mjg59@srcf.ucam.org
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 3/8] sony-laptop: ignore hard switch rfkill events (SPIC)
2011-02-19 3:06 ` Matthew Garrett
@ 2011-02-19 12:46 ` Mattia Dongili
2011-02-19 12:52 ` Thomas Klose
2011-02-19 16:00 ` Matthew Garrett
0 siblings, 2 replies; 15+ messages in thread
From: Mattia Dongili @ 2011-02-19 12:46 UTC (permalink / raw)
To: Matthew Garrett; +Cc: platform-driver-x86, thomas.klose
On Sat, Feb 19, 2011 at 03:06:18AM +0000, Matthew Garrett wrote:
> Do you possibly want to catch these and make sure the kernel rfkill
> state matches the hardware?
hmmmm, to be honest I'm not entirely sure what the actual problem is.
Maybe it's just a timing issue that is made better by avoiding the
input/acpi event generation. For now drop this patch (there is a
different workaround using the mask parameter).
Thomas,
do you still have that TX laptop that had the problem? would you be
available to test a couple of other patches?
Thanks
--
mattia
:wq!
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 3/8] sony-laptop: ignore hard switch rfkill events (SPIC)
2011-02-19 12:46 ` Mattia Dongili
@ 2011-02-19 12:52 ` Thomas Klose
2011-02-19 16:00 ` Matthew Garrett
1 sibling, 0 replies; 15+ messages in thread
From: Thomas Klose @ 2011-02-19 12:52 UTC (permalink / raw)
To: Mattia Dongili; +Cc: Matthew Garrett, platform-driver-x86
Am Samstag, den 19.02.2011, 21:46 +0900 schrieb Mattia Dongili:
> Thomas,
> do you still have that TX laptop that had the problem? would you be
> available to test a couple of other patches?
Yes the TX laptop is still around and is available for testing.
Regards, Thomas
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 3/8] sony-laptop: ignore hard switch rfkill events (SPIC)
2011-02-19 12:46 ` Mattia Dongili
2011-02-19 12:52 ` Thomas Klose
@ 2011-02-19 16:00 ` Matthew Garrett
2011-02-20 3:13 ` Mattia Dongili
1 sibling, 1 reply; 15+ messages in thread
From: Matthew Garrett @ 2011-02-19 16:00 UTC (permalink / raw)
To: Mattia Dongili; +Cc: platform-driver-x86, thomas.klose
On Sat, Feb 19, 2011 at 09:46:54PM +0900, Mattia Dongili wrote:
> On Sat, Feb 19, 2011 at 03:06:18AM +0000, Matthew Garrett wrote:
> > Do you possibly want to catch these and make sure the kernel rfkill
> > state matches the hardware?
>
> hmmmm, to be honest I'm not entirely sure what the actual problem is.
> Maybe it's just a timing issue that is made better by avoiding the
> input/acpi event generation. For now drop this patch (there is a
> different workaround using the mask parameter).
Delivering it to userspace can be racy - rfkill-input will try to toggle
the state as well. So I think this is the right thing to do, but you
might also want to use it to check the current hardware state and update
the state of the rfkill device.
--
Matthew Garrett | mjg59@srcf.ucam.org
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 3/8] sony-laptop: ignore hard switch rfkill events (SPIC)
2011-02-19 16:00 ` Matthew Garrett
@ 2011-02-20 3:13 ` Mattia Dongili
0 siblings, 0 replies; 15+ messages in thread
From: Mattia Dongili @ 2011-02-20 3:13 UTC (permalink / raw)
To: Matthew Garrett; +Cc: platform-driver-x86, thomas.klose
On Sat, Feb 19, 2011 at 04:00:38PM +0000, Matthew Garrett wrote:
> On Sat, Feb 19, 2011 at 09:46:54PM +0900, Mattia Dongili wrote:
> > On Sat, Feb 19, 2011 at 03:06:18AM +0000, Matthew Garrett wrote:
> > > Do you possibly want to catch these and make sure the kernel rfkill
> > > state matches the hardware?
> >
> > hmmmm, to be honest I'm not entirely sure what the actual problem is.
> > Maybe it's just a timing issue that is made better by avoiding the
> > input/acpi event generation. For now drop this patch (there is a
> > different workaround using the mask parameter).
>
> Delivering it to userspace can be racy - rfkill-input will try to toggle
> the state as well. So I think this is the right thing to do, but you
> might also want to use it to check the current hardware state and update
> the state of the rfkill device.
Ah, alright. This makes a lot of sense with what was seen on Thomas'
laptop.
Then if you are ok to keep this patch as is, I'll work on
matching/flipping the rfkill device state separately.
Thanks
--
mattia
:wq!
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 4/8] sony-laptop: use pr_<level> for messages
2011-02-19 2:52 [0/8] sony-laptop for 2.6.39 Mattia Dongili
` (2 preceding siblings ...)
2011-02-19 2:52 ` [PATCH 3/8] sony-laptop: ignore hard switch rfkill events (SPIC) Mattia Dongili
@ 2011-02-19 2:52 ` Mattia Dongili
2011-02-19 2:52 ` [PATCH 5/8] sony-laptop: remove unused Type4 define Mattia Dongili
` (4 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Mattia Dongili @ 2011-02-19 2:52 UTC (permalink / raw)
To: Matthew Garrett; +Cc: platform-driver-x86, Mattia Dongili
Signed-off-by: Mattia Dongili <malattia@linux.it>
---
drivers/platform/x86/sony-laptop.c | 102 ++++++++++++++++-------------------
1 files changed, 47 insertions(+), 55 deletions(-)
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index ad7c496..1662b05 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -71,8 +71,9 @@
#endif
#define DRV_PFX "sony-laptop: "
-#define dprintk(msg...) do { \
- if (debug) printk(KERN_WARNING DRV_PFX msg); \
+#define dprintk(msg...) do { \
+ if (debug) \
+ pr_warn(DRV_PFX msg); \
} while (0)
#define SONY_LAPTOP_DRIVER_VERSION "0.6"
@@ -402,7 +403,7 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device)
error = kfifo_alloc(&sony_laptop_input.fifo,
SONY_LAPTOP_BUF_SIZE, GFP_KERNEL);
if (error) {
- printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n");
+ pr_err(DRV_PFX "kfifo_alloc failed\n");
goto err_dec_users;
}
@@ -686,7 +687,7 @@ static int acpi_callgetfunc(acpi_handle handle, char *name, int *result)
return 0;
}
- printk(KERN_WARNING DRV_PFX "acpi_callreadfunc failed\n");
+ pr_warn(DRV_PFX "acpi_callreadfunc failed\n");
return -1;
}
@@ -712,7 +713,7 @@ static int acpi_callsetfunc(acpi_handle handle, char *name, int value,
if (status == AE_OK) {
if (result != NULL) {
if (out_obj.type != ACPI_TYPE_INTEGER) {
- printk(KERN_WARNING DRV_PFX "acpi_evaluate_object bad "
+ pr_warn(DRV_PFX "acpi_evaluate_object bad "
"return type\n");
return -1;
}
@@ -721,7 +722,7 @@ static int acpi_callsetfunc(acpi_handle handle, char *name, int value,
return 0;
}
- printk(KERN_WARNING DRV_PFX "acpi_evaluate_object failed\n");
+ pr_warn(DRV_PFX "acpi_evaluate_object failed\n");
return -1;
}
@@ -980,7 +981,7 @@ static void sony_nc_notify(struct acpi_device *device, u32 event)
}
if (!key_event->data)
- printk(KERN_INFO DRV_PFX
+ pr_info(DRV_PFX
"Unknown event: 0x%x 0x%x\n",
key_handle,
ev);
@@ -1004,7 +1005,7 @@ static acpi_status sony_walk_callback(acpi_handle handle, u32 level,
struct acpi_device_info *info;
if (ACPI_SUCCESS(acpi_get_object_info(handle, &info))) {
- printk(KERN_WARNING DRV_PFX "method: name: %4.4s, args %X\n",
+ pr_warn(DRV_PFX "method: name: %4.4s, args %X\n",
(char *)&info->name, info->param_count);
kfree(info);
@@ -1045,7 +1046,7 @@ static int sony_nc_resume(struct acpi_device *device)
ret = acpi_callsetfunc(sony_nc_acpi_handle, *item->acpiset,
item->value, NULL);
if (ret < 0) {
- printk("%s: %d\n", __func__, ret);
+ pr_err(DRV_PFX "%s: %d\n", __func__, ret);
break;
}
}
@@ -1065,7 +1066,7 @@ static int sony_nc_resume(struct acpi_device *device)
/* set the last requested brightness level */
if (sony_backlight_device &&
sony_backlight_update_status(sony_backlight_device) < 0)
- printk(KERN_WARNING DRV_PFX "unable to restore brightness level\n");
+ pr_warn(DRV_PFX "unable to restore brightness level\n");
/* re-read rfkill state */
sony_nc_rfkill_update();
@@ -1213,13 +1214,9 @@ static void sony_nc_rfkill_setup(struct acpi_device *device)
}
device_enum = (union acpi_object *) buffer.pointer;
- if (!device_enum) {
- pr_err("Invalid SN06 return object\n");
- goto out_no_enum;
- }
- if (device_enum->type != ACPI_TYPE_BUFFER) {
- pr_err("Invalid SN06 return object type 0x%.2x\n",
- device_enum->type);
+ if (!device_enum || device_enum->type != ACPI_TYPE_BUFFER) {
+ pr_err(DRV_PFX "Invalid SN06 return object 0x%.2x\n",
+ device_enum->type);
goto out_no_enum;
}
@@ -1260,8 +1257,8 @@ static int sony_nc_add(struct acpi_device *device)
acpi_handle handle;
struct sony_nc_value *item;
- printk(KERN_INFO DRV_PFX "%s v%s.\n",
- SONY_NC_DRIVER_NAME, SONY_LAPTOP_DRIVER_VERSION);
+ pr_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");
@@ -1278,10 +1275,11 @@ static int sony_nc_add(struct acpi_device *device)
}
if (debug) {
- status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_nc_acpi_handle,
- 1, sony_walk_callback, NULL, NULL, NULL);
+ status = acpi_walk_namespace(ACPI_TYPE_METHOD,
+ sony_nc_acpi_handle, 1, sony_walk_callback,
+ NULL, NULL, NULL);
if (ACPI_FAILURE(status)) {
- printk(KERN_WARNING DRV_PFX "unable to walk acpi resources\n");
+ pr_warn(DRV_PFX "unable to walk acpi resources\n");
result = -ENODEV;
goto outwalk;
}
@@ -1303,17 +1301,16 @@ static int sony_nc_add(struct acpi_device *device)
/* setup input devices and helper fifo */
result = sony_laptop_setup_input(device);
if (result) {
- printk(KERN_ERR DRV_PFX
- "Unable to create input devices.\n");
+ pr_err(DRV_PFX "Unable to create input devices.\n");
goto outwalk;
}
if (acpi_video_backlight_support()) {
- printk(KERN_INFO DRV_PFX "brightness ignored, must be "
+ pr_info(DRV_PFX "brightness ignored, must be "
"controlled by ACPI video driver\n");
} else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT",
&handle))) {
- struct backlight_properties props;
+ struct backlight_properties props;
memset(&props, 0, sizeof(struct backlight_properties));
props.max_brightness = SONY_MAX_BRIGHTNESS - 1;
sony_backlight_device = backlight_device_register("sony", NULL,
@@ -1322,7 +1319,7 @@ static int sony_nc_add(struct acpi_device *device)
&props);
if (IS_ERR(sony_backlight_device)) {
- printk(KERN_WARNING DRV_PFX "unable to register backlight device\n");
+ pr_warning(DRV_PFX "unable to register backlight device\n");
sony_backlight_device = NULL;
} else {
sony_backlight_device->props.brightness =
@@ -1849,7 +1846,7 @@ out:
if (pcidev)
pci_dev_put(pcidev);
- printk(KERN_INFO DRV_PFX "detected Type%d model\n",
+ pr_info(DRV_PFX "detected Type%d model\n",
dev->model == SONYPI_DEVICE_TYPE1 ? 1 :
dev->model == SONYPI_DEVICE_TYPE2 ? 2 : 3);
}
@@ -1897,7 +1894,7 @@ static int __sony_pic_camera_ready(void)
static int __sony_pic_camera_off(void)
{
if (!camera) {
- printk(KERN_WARNING DRV_PFX "camera control not enabled\n");
+ pr_warn(DRV_PFX "camera control not enabled\n");
return -ENODEV;
}
@@ -1917,7 +1914,7 @@ static int __sony_pic_camera_on(void)
int i, j, x;
if (!camera) {
- printk(KERN_WARNING DRV_PFX "camera control not enabled\n");
+ pr_warn(DRV_PFX "camera control not enabled\n");
return -ENODEV;
}
@@ -1940,7 +1937,7 @@ static int __sony_pic_camera_on(void)
}
if (j == 0) {
- printk(KERN_WARNING DRV_PFX "failed to power on camera\n");
+ pr_warn(DRV_PFX "failed to power on camera\n");
return -ENODEV;
}
@@ -1996,7 +1993,7 @@ int sony_pic_camera_command(int command, u8 value)
ITERATIONS_SHORT);
break;
default:
- printk(KERN_ERR DRV_PFX "sony_pic_camera_command invalid: %d\n",
+ pr_err(DRV_PFX "sony_pic_camera_command invalid: %d\n",
command);
break;
}
@@ -2403,7 +2400,7 @@ static int sonypi_compat_init(void)
error =
kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL);
if (error) {
- printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n");
+ pr_err(DRV_PFX "kfifo_alloc failed\n");
return error;
}
@@ -2413,11 +2410,11 @@ static int sonypi_compat_init(void)
sonypi_misc_device.minor = minor;
error = misc_register(&sonypi_misc_device);
if (error) {
- printk(KERN_ERR DRV_PFX "misc_register failed\n");
+ pr_err(DRV_PFX "misc_register failed\n");
goto err_free_kfifo;
}
if (minor == -1)
- printk(KERN_INFO DRV_PFX "device allocated minor is %d\n",
+ pr_info(DRV_PFX "device allocated minor is %d\n",
sonypi_misc_device.minor);
return 0;
@@ -2477,8 +2474,7 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context)
}
for (i = 0; i < p->interrupt_count; i++) {
if (!p->interrupts[i]) {
- printk(KERN_WARNING DRV_PFX
- "Invalid IRQ %d\n",
+ pr_warn(DRV_PFX "Invalid IRQ %d\n",
p->interrupts[i]);
continue;
}
@@ -2517,7 +2513,7 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context)
ioport->io2.address_length);
}
else {
- printk(KERN_ERR DRV_PFX "Unknown SPIC Type, more than 2 IO Ports\n");
+ pr_err(DRV_PFX "Unknown SPIC Type, more than 2 IO Ports\n");
return AE_ERROR;
}
return AE_OK;
@@ -2545,7 +2541,7 @@ static int sony_pic_possible_resources(struct acpi_device *device)
dprintk("Evaluating _STA\n");
result = acpi_bus_get_status(device);
if (result) {
- printk(KERN_WARNING DRV_PFX "Unable to read status\n");
+ pr_warn(DRV_PFX "Unable to read status\n");
goto end;
}
@@ -2561,8 +2557,7 @@ static int sony_pic_possible_resources(struct acpi_device *device)
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",
+ pr_warn(DRV_PFX "Failure evaluating %s\n",
METHOD_NAME__PRS);
result = -ENODEV;
}
@@ -2676,7 +2671,7 @@ static int sony_pic_enable(struct acpi_device *device,
/* check for total failure */
if (ACPI_FAILURE(status)) {
- printk(KERN_ERR DRV_PFX "Error evaluating _SRS\n");
+ pr_err(DRV_PFX "Error evaluating _SRS\n");
result = -ENODEV;
goto end;
}
@@ -2768,7 +2763,7 @@ static int sony_pic_remove(struct acpi_device *device, int type)
struct sony_pic_irq *irq, *tmp_irq;
if (sony_pic_disable(device)) {
- printk(KERN_ERR DRV_PFX "Couldn't disable device.\n");
+ pr_err(DRV_PFX "Couldn't disable device.\n");
return -ENXIO;
}
@@ -2808,8 +2803,8 @@ static int sony_pic_add(struct acpi_device *device)
struct sony_pic_ioport *io, *tmp_io;
struct sony_pic_irq *irq, *tmp_irq;
- printk(KERN_INFO DRV_PFX "%s v%s.\n",
- SONY_PIC_DRIVER_NAME, SONY_LAPTOP_DRIVER_VERSION);
+ pr_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");
@@ -2819,16 +2814,14 @@ static int sony_pic_add(struct acpi_device *device)
/* read _PRS resources */
result = sony_pic_possible_resources(device);
if (result) {
- printk(KERN_ERR DRV_PFX
- "Unable to read possible resources.\n");
+ pr_err(DRV_PFX "Unable to read possible resources.\n");
goto err_free_resources;
}
/* setup input devices and helper fifo */
result = sony_laptop_setup_input(device);
if (result) {
- printk(KERN_ERR DRV_PFX
- "Unable to create input devices.\n");
+ pr_err(DRV_PFX "Unable to create input devices.\n");
goto err_free_resources;
}
@@ -2869,7 +2862,7 @@ static int sony_pic_add(struct acpi_device *device)
}
}
if (!spic_dev.cur_ioport) {
- printk(KERN_ERR DRV_PFX "Failed to request_region.\n");
+ pr_err(DRV_PFX "Failed to request_region.\n");
result = -ENODEV;
goto err_remove_compat;
}
@@ -2889,7 +2882,7 @@ static int sony_pic_add(struct acpi_device *device)
}
}
if (!spic_dev.cur_irq) {
- printk(KERN_ERR DRV_PFX "Failed to request_irq.\n");
+ pr_err(DRV_PFX "Failed to request_irq.\n");
result = -ENODEV;
goto err_release_region;
}
@@ -2897,7 +2890,7 @@ static int sony_pic_add(struct acpi_device *device)
/* 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");
+ pr_err(DRV_PFX "Couldn't enable device.\n");
goto err_free_irq;
}
@@ -3006,8 +2999,7 @@ static int __init sony_laptop_init(void)
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.");
+ pr_err(DRV_PFX "Unable to register SPIC driver.");
goto out;
}
spic_drv_registered = 1;
@@ -3015,7 +3007,7 @@ static int __init sony_laptop_init(void)
result = acpi_bus_register_driver(&sony_nc_driver);
if (result) {
- printk(KERN_ERR DRV_PFX "Unable to register SNC driver.");
+ pr_err(DRV_PFX "Unable to register SNC driver.");
goto out_unregister_pic;
}
--
1.7.2.3
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH 5/8] sony-laptop: remove unused Type4 define
2011-02-19 2:52 [0/8] sony-laptop for 2.6.39 Mattia Dongili
` (3 preceding siblings ...)
2011-02-19 2:52 ` [PATCH 4/8] sony-laptop: use pr_<level> for messages Mattia Dongili
@ 2011-02-19 2:52 ` Mattia Dongili
2011-02-19 2:52 ` [PATCH 6/8] sony-laptop: cache handles and report them via sysfs Mattia Dongili
` (3 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Mattia Dongili @ 2011-02-19 2:52 UTC (permalink / raw)
To: Matthew Garrett; +Cc: platform-driver-x86, Mattia Dongili
Signed-off-by: Mattia Dongili <malattia@linux.it>
---
drivers/platform/x86/sony-laptop.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index 1662b05..22519a4 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -1442,7 +1442,6 @@ static struct acpi_driver sony_nc_driver = {
#define SONYPI_DEVICE_TYPE1 0x00000001
#define SONYPI_DEVICE_TYPE2 0x00000002
#define SONYPI_DEVICE_TYPE3 0x00000004
-#define SONYPI_DEVICE_TYPE4 0x00000008
#define SONYPI_TYPE1_OFFSET 0x04
#define SONYPI_TYPE2_OFFSET 0x12
--
1.7.2.3
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH 6/8] sony-laptop: cache handles and report them via sysfs
2011-02-19 2:52 [0/8] sony-laptop for 2.6.39 Mattia Dongili
` (4 preceding siblings ...)
2011-02-19 2:52 ` [PATCH 5/8] sony-laptop: remove unused Type4 define Mattia Dongili
@ 2011-02-19 2:52 ` Mattia Dongili
2011-02-19 2:52 ` [PATCH 7/8] sony-laptop: implement keyboard backlight support Mattia Dongili
` (2 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Mattia Dongili @ 2011-02-19 2:52 UTC (permalink / raw)
To: Matthew Garrett; +Cc: platform-driver-x86, Mattia Dongili
Avoid calling into acpi each time we need to lookup a method handle
and report the available handles to ease collection of information when
debugging issues. Also move initialization of the platform driver
earlier to allow adding files from other setup functions.
Signed-off-by: Mattia Dongili <malattia@linux.it>
---
drivers/platform/x86/sony-laptop.c | 97 ++++++++++++++++++++++++++++++------
1 files changed, 81 insertions(+), 16 deletions(-)
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index 22519a4..1585d37 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -727,20 +727,79 @@ static int acpi_callsetfunc(acpi_handle handle, char *name, int value,
return -1;
}
-static int sony_find_snc_handle(int handle)
+struct sony_nc_handles {
+ u16 cap[0x10];
+ struct device_attribute devattr;
+};
+
+struct sony_nc_handles *handles;
+
+static ssize_t sony_nc_handles_show(struct device *dev,
+ struct device_attribute *attr, char *buffer)
+{
+ ssize_t len = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(handles->cap); i++) {
+ len += snprintf(buffer + len, PAGE_SIZE - len, "0x%.4x ",
+ handles->cap[i]);
+ }
+ len += snprintf(buffer + len, PAGE_SIZE - len, "\n");
+
+ return len;
+}
+
+static int sony_nc_handles_setup(struct platform_device *pd)
{
int i;
int result;
- for (i = 0x20; i < 0x30; i++) {
- acpi_callsetfunc(sony_nc_acpi_handle, "SN00", i, &result);
- if (result == handle) {
- dprintk("found handle 0x%.4x (offset: 0x%.2x)\n",
- handle, i - 0x20);
- return i-0x20;
+ handles = kzalloc(sizeof(*handles), GFP_KERNEL);
+
+ sysfs_attr_init(handles->devattr);
+ handles->devattr.attr.name = "handles";
+ handles->devattr.attr.mode = S_IRUGO;
+ handles->devattr.show = sony_nc_handles_show;
+
+ for (i = 0; i < ARRAY_SIZE(handles->cap); i++) {
+ if (!acpi_callsetfunc(sony_nc_acpi_handle,
+ "SN00", i + 0x20, &result)) {
+ dprintk("caching handle 0x%.4x (offset: 0x%.2x)\n",
+ result, i);
+ handles->cap[i] = result;
}
}
+ /* allow reading capabilities via sysfs */
+ if (device_create_file(&pd->dev, &handles->devattr)) {
+ kfree(handles);
+ handles = NULL;
+ return -1;
+ }
+
+ return 0;
+}
+
+static int sony_nc_handles_cleanup(struct platform_device *pd)
+{
+ if (handles) {
+ device_remove_file(&pd->dev, &handles->devattr);
+ kfree(handles);
+ handles = NULL;
+ }
+ return 0;
+}
+
+static int sony_find_snc_handle(int handle)
+{
+ int i;
+ for (i = 0; i < 0x10; i++) {
+ if (handles->cap[i] == handle) {
+ dprintk("found handle 0x%.4x (offset: 0x%.2x)\n",
+ handle, i);
+ return i;
+ }
+ }
dprintk("handle 0x%.4x not found\n", handle);
return -1;
}
@@ -1274,6 +1333,10 @@ static int sony_nc_add(struct acpi_device *device)
goto outwalk;
}
+ result = sony_pf_add();
+ if (result)
+ goto outpresent;
+
if (debug) {
status = acpi_walk_namespace(ACPI_TYPE_METHOD,
sony_nc_acpi_handle, 1, sony_walk_callback,
@@ -1281,7 +1344,7 @@ static int sony_nc_add(struct acpi_device *device)
if (ACPI_FAILURE(status)) {
pr_warn(DRV_PFX "unable to walk acpi resources\n");
result = -ENODEV;
- goto outwalk;
+ goto outpresent;
}
}
@@ -1294,6 +1357,8 @@ static int sony_nc_add(struct acpi_device *device)
if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "SN00",
&handle))) {
dprintk("Doing SNC setup\n");
+ if (sony_nc_handles_setup(sony_pf_device))
+ goto outpresent;
sony_nc_function_setup(device);
sony_nc_rfkill_setup(device);
}
@@ -1302,7 +1367,7 @@ static int sony_nc_add(struct acpi_device *device)
result = sony_laptop_setup_input(device);
if (result) {
pr_err(DRV_PFX "Unable to create input devices.\n");
- goto outwalk;
+ goto outsnc;
}
if (acpi_video_backlight_support()) {
@@ -1329,10 +1394,6 @@ static int sony_nc_add(struct acpi_device *device)
}
- result = sony_pf_add();
- if (result)
- goto outbacklight;
-
/* create sony_pf sysfs attributes related to the SNC device */
for (item = sony_nc_values; item->name; ++item) {
@@ -1378,14 +1439,17 @@ static int sony_nc_add(struct acpi_device *device)
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);
sony_laptop_remove_input();
+ outsnc:
+ sony_nc_handles_cleanup(sony_pf_device);
+
+ outpresent:
+ sony_pf_remove();
+
outwalk:
sony_nc_rfkill_cleanup();
return result;
@@ -1404,6 +1468,7 @@ static int sony_nc_remove(struct acpi_device *device, int type)
device_remove_file(&sony_pf_device->dev, &item->devattr);
}
+ sony_nc_handles_cleanup(sony_pf_device);
sony_pf_remove();
sony_laptop_remove_input();
sony_nc_rfkill_cleanup();
--
1.7.2.3
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH 7/8] sony-laptop: implement keyboard backlight support
2011-02-19 2:52 [0/8] sony-laptop for 2.6.39 Mattia Dongili
` (5 preceding siblings ...)
2011-02-19 2:52 ` [PATCH 6/8] sony-laptop: cache handles and report them via sysfs Mattia Dongili
@ 2011-02-19 2:52 ` Mattia Dongili
2011-02-19 2:52 ` [PATCH 8/8] sony-laptop: implement new backlight control method Mattia Dongili
2011-02-21 20:51 ` [0/8] sony-laptop for 2.6.39 Matthew Garrett
8 siblings, 0 replies; 15+ messages in thread
From: Mattia Dongili @ 2011-02-19 2:52 UTC (permalink / raw)
To: Matthew Garrett; +Cc: platform-driver-x86, Mattia Dongili
Recent Vaios have the opportunity to control the keyboard backlight via
ACPI calls to the SNC device.
Introduce two module parameters to control how keyboard backlight should
be set at module loading (default to on and with 10 seconds timeout).
Tested-by: Marco Chiappero <marco@absence.it>
Signed-off-by: Mattia Dongili <malattia@linux.it>
---
drivers/platform/x86/sony-laptop.c | 176 +++++++++++++++++++++++++++++++++++-
1 files changed, 175 insertions(+), 1 deletions(-)
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index 1585d37..cff1b85 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -125,6 +125,19 @@ MODULE_PARM_DESC(minor,
"default is -1 (automatic)");
#endif
+static int kbd_backlight; /* = 1 */
+module_param(kbd_backlight, int, 0444);
+MODULE_PARM_DESC(kbd_backlight,
+ "set this to 0 to disable keyboard backlight, "
+ "1 to enable it (default: 0)");
+
+static int kbd_backlight_timeout; /* = 0 */
+module_param(kbd_backlight_timeout, int, 0444);
+MODULE_PARM_DESC(kbd_backlight_timeout,
+ "set this to 0 to set the default 10 seconds timeout, "
+ "1 for 30 seconds, 2 for 60 seconds and 3 to disable timeout "
+ "(default: 0)");
+
enum sony_nc_rfkill {
SONY_WIFI,
SONY_BLUETOOTH,
@@ -1309,6 +1322,161 @@ out_no_enum:
return;
}
+/* Keyboard backlight feature */
+#define KBDBL_HANDLER 0x137
+#define KBDBL_PRESENT 0xB00
+#define SET_MODE 0xC00
+#define SET_TIMEOUT 0xE00
+
+struct kbd_backlight {
+ int mode;
+ int timeout;
+ struct device_attribute mode_attr;
+ struct device_attribute timeout_attr;
+};
+
+struct kbd_backlight *kbdbl_handle;
+
+static ssize_t __sony_nc_kbd_backlight_mode_set(u8 value)
+{
+ int result;
+
+ if (value > 1)
+ return -EINVAL;
+
+ if (sony_call_snc_handle(KBDBL_HANDLER,
+ (value << 0x10) | SET_MODE, &result))
+ return -EIO;
+
+ kbdbl_handle->mode = value;
+
+ return 0;
+}
+
+static ssize_t sony_nc_kbd_backlight_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buffer, size_t count)
+{
+ int ret = 0;
+ unsigned long value;
+
+ if (count > 31)
+ return -EINVAL;
+
+ if (strict_strtoul(buffer, 10, &value))
+ return -EINVAL;
+
+ ret = __sony_nc_kbd_backlight_mode_set(value);
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static ssize_t sony_nc_kbd_backlight_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buffer)
+{
+ ssize_t count = 0;
+ count = snprintf(buffer, PAGE_SIZE, "%d\n", kbdbl_handle->mode);
+ return count;
+}
+
+static int __sony_nc_kbd_backlight_timeout_set(u8 value)
+{
+ int result;
+
+ if (value > 3)
+ return -EINVAL;
+
+ if (sony_call_snc_handle(KBDBL_HANDLER,
+ (value << 0x10) | SET_TIMEOUT, &result))
+ return -EIO;
+
+ kbdbl_handle->timeout = value;
+
+ return 0;
+}
+
+static ssize_t sony_nc_kbd_backlight_timeout_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buffer, size_t count)
+{
+ int ret = 0;
+ unsigned long value;
+
+ if (count > 31)
+ return -EINVAL;
+
+ if (strict_strtoul(buffer, 10, &value))
+ return -EINVAL;
+
+ ret = __sony_nc_kbd_backlight_timeout_set(value);
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static ssize_t sony_nc_kbd_backlight_timeout_show(struct device *dev,
+ struct device_attribute *attr, char *buffer)
+{
+ ssize_t count = 0;
+ count = snprintf(buffer, PAGE_SIZE, "%d\n", kbdbl_handle->timeout);
+ return count;
+}
+
+static int sony_nc_kbd_backlight_setup(struct platform_device *pd)
+{
+ int result;
+
+ if (sony_call_snc_handle(0x137, KBDBL_PRESENT, &result))
+ return 0;
+ if (!(result & 0x02))
+ return 0;
+
+ kbdbl_handle = kzalloc(sizeof(*kbdbl_handle), GFP_KERNEL);
+
+ sysfs_attr_init(kbdbl_handle->mode_attr);
+ kbdbl_handle->mode_attr.attr.name = "kbd_backlight";
+ kbdbl_handle->mode_attr.attr.mode = S_IRUGO | S_IWUSR;
+ kbdbl_handle->mode_attr.show = sony_nc_kbd_backlight_mode_show;
+ kbdbl_handle->mode_attr.store = sony_nc_kbd_backlight_mode_store;
+
+ sysfs_attr_init(kbdbl_handle->timeout_attr);
+ kbdbl_handle->timeout_attr.attr.name = "kbd_backlight_timeout";
+ kbdbl_handle->timeout_attr.attr.mode = S_IRUGO | S_IWUSR;
+ kbdbl_handle->timeout_attr.show = sony_nc_kbd_backlight_timeout_show;
+ kbdbl_handle->timeout_attr.store = sony_nc_kbd_backlight_timeout_store;
+
+ if (device_create_file(&pd->dev, &kbdbl_handle->mode_attr))
+ goto outkzalloc;
+
+ if (device_create_file(&pd->dev, &kbdbl_handle->timeout_attr))
+ goto outmode;
+
+ __sony_nc_kbd_backlight_mode_set(kbd_backlight);
+ __sony_nc_kbd_backlight_timeout_set(kbd_backlight_timeout);
+
+ return 0;
+
+outmode:
+ device_remove_file(&pd->dev, &kbdbl_handle->mode_attr);
+outkzalloc:
+ kfree(kbdbl_handle);
+ kbdbl_handle = NULL;
+ return -1;
+}
+
+static int sony_nc_kbd_backlight_cleanup(struct platform_device *pd)
+{
+ if (kbdbl_handle) {
+ device_remove_file(&pd->dev, &kbdbl_handle->mode_attr);
+ device_remove_file(&pd->dev, &kbdbl_handle->timeout_attr);
+ kfree(kbdbl_handle);
+ }
+ return 0;
+}
+
static int sony_nc_add(struct acpi_device *device)
{
acpi_status status;
@@ -1359,6 +1527,8 @@ static int sony_nc_add(struct acpi_device *device)
dprintk("Doing SNC setup\n");
if (sony_nc_handles_setup(sony_pf_device))
goto outpresent;
+ if (sony_nc_kbd_backlight_setup(sony_pf_device))
+ goto outsnc;
sony_nc_function_setup(device);
sony_nc_rfkill_setup(device);
}
@@ -1367,7 +1537,7 @@ static int sony_nc_add(struct acpi_device *device)
result = sony_laptop_setup_input(device);
if (result) {
pr_err(DRV_PFX "Unable to create input devices.\n");
- goto outsnc;
+ goto outkbdbacklight;
}
if (acpi_video_backlight_support()) {
@@ -1444,6 +1614,9 @@ static int sony_nc_add(struct acpi_device *device)
sony_laptop_remove_input();
+ outkbdbacklight:
+ sony_nc_kbd_backlight_cleanup(sony_pf_device);
+
outsnc:
sony_nc_handles_cleanup(sony_pf_device);
@@ -1468,6 +1641,7 @@ static int sony_nc_remove(struct acpi_device *device, int type)
device_remove_file(&sony_pf_device->dev, &item->devattr);
}
+ sony_nc_kbd_backlight_cleanup(sony_pf_device);
sony_nc_handles_cleanup(sony_pf_device);
sony_pf_remove();
sony_laptop_remove_input();
--
1.7.2.3
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH 8/8] sony-laptop: implement new backlight control method
2011-02-19 2:52 [0/8] sony-laptop for 2.6.39 Mattia Dongili
` (6 preceding siblings ...)
2011-02-19 2:52 ` [PATCH 7/8] sony-laptop: implement keyboard backlight support Mattia Dongili
@ 2011-02-19 2:52 ` Mattia Dongili
2011-02-21 20:51 ` [0/8] sony-laptop for 2.6.39 Matthew Garrett
8 siblings, 0 replies; 15+ messages in thread
From: Mattia Dongili @ 2011-02-19 2:52 UTC (permalink / raw)
To: Matthew Garrett; +Cc: platform-driver-x86, Mattia Dongili
Reasonably recent Vaios have a 0x12f or 0x137 handler that exposes a
fine lid backlight regulation with values ranging from 0 to 255.
The patch is based on findings and code from Javier Achirica
<achirica@gmail.com> and Marco Chiappero <marco@absence.it>
Signed-off-by: Mattia Dongili <malattia@linux.it>
---
drivers/platform/x86/sony-laptop.c | 108 ++++++++++++++++++++++++++----------
1 files changed, 78 insertions(+), 30 deletions(-)
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index cff1b85..a097a27 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -938,11 +938,39 @@ static int sony_backlight_get_brightness(struct backlight_device *bd)
return value - 1;
}
-static struct backlight_device *sony_backlight_device;
+static int sony_nc_get_brightness_ng(struct backlight_device *bd)
+{
+ int result;
+ int *handle = (int *)bl_get_data(bd);
+
+ sony_call_snc_handle(*handle, 0x0200, &result);
+
+ return result & 0xff;
+}
+
+static int sony_nc_update_status_ng(struct backlight_device *bd)
+{
+ int value, result;
+ int *handle = (int *)bl_get_data(bd);
+
+ value = bd->props.brightness;
+ sony_call_snc_handle(*handle, 0x0100 | (value << 16), &result);
+
+ return sony_nc_get_brightness_ng(bd);
+}
+
static const struct backlight_ops sony_backlight_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
.update_status = sony_backlight_update_status,
.get_brightness = sony_backlight_get_brightness,
};
+static const struct backlight_ops sony_backlight_ng_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .update_status = sony_nc_update_status_ng,
+ .get_brightness = sony_nc_get_brightness_ng,
+};
+static int backlight_ng_handle;
+static struct backlight_device *sony_backlight_device;
/*
* New SNC-only Vaios event mapping to driver known keys
@@ -1135,11 +1163,6 @@ static int sony_nc_resume(struct acpi_device *device)
sony_nc_function_setup(device);
}
- /* set the last requested brightness level */
- if (sony_backlight_device &&
- sony_backlight_update_status(sony_backlight_device) < 0)
- pr_warn(DRV_PFX "unable to restore brightness level\n");
-
/* re-read rfkill state */
sony_nc_rfkill_update();
@@ -1477,6 +1500,51 @@ static int sony_nc_kbd_backlight_cleanup(struct platform_device *pd)
return 0;
}
+static void sony_nc_backlight_setup(void)
+{
+ acpi_handle unused;
+ int max_brightness = 0;
+ const struct backlight_ops *ops = NULL;
+ struct backlight_properties props;
+
+ if (sony_find_snc_handle(0x12f) != -1) {
+ backlight_ng_handle = 0x12f;
+ ops = &sony_backlight_ng_ops;
+ max_brightness = 0xff;
+
+ } else if (sony_find_snc_handle(0x137) != -1) {
+ backlight_ng_handle = 0x137;
+ ops = &sony_backlight_ng_ops;
+ max_brightness = 0xff;
+
+ } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT",
+ &unused))) {
+ ops = &sony_backlight_ops;
+ max_brightness = SONY_MAX_BRIGHTNESS - 1;
+
+ } else
+ return;
+
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = max_brightness;
+ sony_backlight_device = backlight_device_register("sony", NULL,
+ &backlight_ng_handle,
+ ops, &props);
+
+ if (IS_ERR(sony_backlight_device)) {
+ pr_warning(DRV_PFX "unable to register backlight device\n");
+ sony_backlight_device = NULL;
+ } else
+ sony_backlight_device->props.brightness =
+ ops->get_brightness(sony_backlight_device);
+}
+
+static void sony_nc_backlight_cleanup(void)
+{
+ if (sony_backlight_device)
+ backlight_device_unregister(sony_backlight_device);
+}
+
static int sony_nc_add(struct acpi_device *device)
{
acpi_status status;
@@ -1543,26 +1611,8 @@ static int sony_nc_add(struct acpi_device *device)
if (acpi_video_backlight_support()) {
pr_info(DRV_PFX "brightness ignored, must be "
"controlled by ACPI video driver\n");
- } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT",
- &handle))) {
- struct backlight_properties props;
- memset(&props, 0, sizeof(struct backlight_properties));
- props.max_brightness = SONY_MAX_BRIGHTNESS - 1;
- sony_backlight_device = backlight_device_register("sony", NULL,
- NULL,
- &sony_backlight_ops,
- &props);
-
- if (IS_ERR(sony_backlight_device)) {
- pr_warning(DRV_PFX "unable to register backlight device\n");
- sony_backlight_device = NULL;
- } else {
- sony_backlight_device->props.brightness =
- sony_backlight_get_brightness
- (sony_backlight_device);
- }
-
- }
+ } else
+ sony_nc_backlight_setup();
/* create sony_pf sysfs attributes related to the SNC device */
for (item = sony_nc_values; item->name; ++item) {
@@ -1609,8 +1659,7 @@ static int sony_nc_add(struct acpi_device *device)
for (item = sony_nc_values; item->name; ++item) {
device_remove_file(&sony_pf_device->dev, &item->devattr);
}
- if (sony_backlight_device)
- backlight_device_unregister(sony_backlight_device);
+ sony_nc_backlight_cleanup();
sony_laptop_remove_input();
@@ -1632,8 +1681,7 @@ static int sony_nc_remove(struct acpi_device *device, int type)
{
struct sony_nc_value *item;
- if (sony_backlight_device)
- backlight_device_unregister(sony_backlight_device);
+ sony_nc_backlight_cleanup();
sony_nc_acpi_device = NULL;
--
1.7.2.3
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [0/8] sony-laptop for 2.6.39
2011-02-19 2:52 [0/8] sony-laptop for 2.6.39 Mattia Dongili
` (7 preceding siblings ...)
2011-02-19 2:52 ` [PATCH 8/8] sony-laptop: implement new backlight control method Mattia Dongili
@ 2011-02-21 20:51 ` Matthew Garrett
8 siblings, 0 replies; 15+ messages in thread
From: Matthew Garrett @ 2011-02-21 20:51 UTC (permalink / raw)
To: Mattia Dongili; +Cc: platform-driver-x86
Applied the series for -next. THanks!
--
Matthew Garrett | mjg59@srcf.ucam.org
^ permalink raw reply [flat|nested] 15+ messages in thread