From patchwork Mon Mar 23 16:34:59 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Norbert Preining X-Patchwork-Id: 13760 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n2NGZUaB017215 for ; Mon, 23 Mar 2009 16:35:30 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754633AbZCWQfJ (ORCPT ); Mon, 23 Mar 2009 12:35:09 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753728AbZCWQfJ (ORCPT ); Mon, 23 Mar 2009 12:35:09 -0400 Received: from mx.logic.tuwien.ac.at ([128.130.175.19]:41153 "EHLO mx.logic.tuwien.ac.at" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754633AbZCWQfG (ORCPT ); Mon, 23 Mar 2009 12:35:06 -0400 Received: from gamma.logic.tuwien.ac.at ([128.130.175.3] ident=Debian-exim) by mx.logic.tuwien.ac.at with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.63) (envelope-from ) id 1Lln75-00062T-R0; Mon, 23 Mar 2009 17:34:59 +0100 Received: from preining by gamma.logic.tuwien.ac.at with local (Exim 4.63) (envelope-from ) id 1Lln75-0001dT-O5; Mon, 23 Mar 2009 17:34:59 +0100 Date: Mon, 23 Mar 2009 17:34:59 +0100 To: sony-vaio-z-series@lists.launchpad.net Cc: Matthew Garrett , Mattia Dongili , Matthias Welwarsky , linux-acpi@vger.kernel.org Subject: new fixes for sony-acpi Message-ID: <20090323163459.GB5463@gamma.logic.tuwien.ac.at> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.13 (2006-08-11) From: Norbert Preining Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org Hi Sony Vaio Z list, after some discussion Matthew has provided a nice patch that makes the Fn-F5 and Fn-F6 keys working, and also S1 and S2. I have adapted the speed-stamina patch from Matthias. The following patches are only interesting for people running 2.6.29-rc kernels (afais) So attached are two patches: - sony-laptop-matthew-version5.patch latest version from Matthew with some keys creating events - sony-laptop.c-speed-stamina-latest.patch patch to add speed-stamina switch based on the 0.7 module of Matthias Thanks a lot to Matthew and Matthias for working on that. Best wishes Norbert ------------------------------------------------------------------------------- Dr. Norbert Preining Vienna University of Technology Debian Developer Debian TeX Group gpg DSA: 0x09C5B094 fp: 14DF 2E6C 0307 BE6D AD76 A9C0 D2BF 4AA3 09C5 B094 ------------------------------------------------------------------------------- HIGH LIMERIGG (n.) The topmost tread of a staircase which disappears when you've climbing the stairs in the darkness. --- Douglas Adams, The Meaning of Liff --- sony-laptop.c-2.6.29-rc8-matthew5 2009-03-23 17:31:19.000000000 +0100 +++ sony-laptop.c 2009-03-23 17:32:29.000000000 +0100 @@ -3,6 +3,7 @@ * * Copyright (C) 2004-2005 Stelian Pop * Copyright (C) 2007 Mattia Dongili + * Copyright (C) 2009 Matthias Welwarsky * * Parts of this driver inspired from asus_acpi.c and ibm_acpi.c * which are copyrighted by their respective authors. @@ -115,6 +116,11 @@ "set this to 1 to enable Motion Eye camera controls " "(only use it if you have a C1VE or C1VN model)"); +static int speed_stamina; +module_param(speed_stamina, int, 0444); +MODULE_PARM_DESC(speed_stamina, + "Set this to 1 to enable SPEED mode on module load (EXPERIMENTAL)"); + #ifdef CONFIG_SONYPI_COMPAT static int minor = -1; module_param(minor, int, 0); @@ -475,9 +481,161 @@ } /*********** Platform Device ***********/ +static int sony_ovga_dsm(int func, int arg) +{ + static char *path = "\\_SB.PCI0.OVGA._DSM"; + static char muid[] = { + /*00*/ 0xA0, 0xA0, 0x95, 0x9D, 0x60, 0x00, 0x48, 0x4D, /* MUID */ + /*08*/ 0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4, + }; + + struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_object_list input; + union acpi_object params[4]; + int result; + + input.count = 4; + input.pointer = params; + params[0].type = ACPI_TYPE_BUFFER; + params[0].buffer.length = sizeof(muid); + params[0].buffer.pointer = (char*)muid; + params[1].type = ACPI_TYPE_INTEGER; + params[1].integer.value = 0x00000102; + params[2].type = ACPI_TYPE_INTEGER; + params[2].integer.value = func; + params[3].type = ACPI_TYPE_INTEGER; + params[3].integer.value = arg; + + result = acpi_evaluate_object(NULL, (char*)path, &input, &output); + if (result) { + printk("%s failed: %d\n", path, result); + return -1; + } + +#ifdef DEBUG + { + union acpi_object *obj = (union acpi_object*)output.pointer; + if (obj->type == ACPI_TYPE_PACKAGE) { + int i; + printk("returned package sized %d\n", obj->package.count); + for (i = 0; i < obj->package.count; i++) + printk("%d %08x\n", i, obj->package.elements[i].integer.value); + } else + if (obj->type == ACPI_TYPE_INTEGER) { + printk("returned integer %08X\n", obj->integer.value); + } else + if (obj->type == ACPI_TYPE_BUFFER) { + int i; + printk("returned buffer sized %d\n", obj->buffer.length); + for (i = 0; i < obj->buffer.length; i++) + printk("%d %02x\n", i, obj->buffer.pointer[i]); + } + } +#endif + kfree(output.pointer); + return 0; +} + +static int sony_led_stamina(void) +{ + return sony_ovga_dsm(2, 0x11); +} + +static int sony_led_speed(void) +{ + return sony_ovga_dsm(2, 0x12); +} + +#ifdef DEBUG +static int sony_led_off(void) +{ + return sony_ovga_dsm(2, 0x13); +} + +static int sony_dgpu_sta(void) +{ + return sony_ovga_dsm(3, 0x00); +} +#endif + +static int sony_dgpu_off(void) +{ + return sony_ovga_dsm(3, 0x02); +} + +static int sony_dgpu_on(void) +{ + return sony_ovga_dsm(3, 0x01); +} + +static ssize_t sony_pf_store_speed_stamina(struct device *dev, + struct device_attribute *attr, + const char *buffer, size_t count) +{ + if (!strncmp(buffer, "speed", strlen("speed"))) { + sony_dgpu_on(); + sony_led_speed(); + speed_stamina = 1; + } else + if (!strncmp(buffer, "stamina", strlen("stamina"))) { + sony_dgpu_off(); + sony_led_stamina(); + speed_stamina = 0; + } else + return -EINVAL; + + return count; +} + +static ssize_t sony_pf_show_speed_stamina(struct device *dev, + struct device_attribute *attr, char *buffer) +{ + return snprintf(buffer, PAGE_SIZE, "%s\n", speed_stamina ? "speed":"stamina"); +} + +static struct device_attribute sony_pf_speed_stamina_attr = + __ATTR(speed_stamina, S_IWUSR|S_IRUGO, + sony_pf_show_speed_stamina, sony_pf_store_speed_stamina); + +static int sony_pf_probe(struct platform_device *pdev) +{ + int result; + + result = device_create_file(&pdev->dev, &sony_pf_speed_stamina_attr); + if (result) + printk(KERN_DEBUG "sony_pf_probe: failed to add speed/stamina switch\n"); + + /* initialize default, look at module param speed_stamina */ + if (speed_stamina == 1) { + sony_dgpu_on(); + sony_led_speed(); + } else { + sony_dgpu_off(); + sony_led_stamina(); + } + + return 0; +} + +static int sony_pf_resume(struct platform_device *pdev) +{ + /* on resume, restore previous state */ + if (speed_stamina == 1) { + sony_dgpu_on(); + sony_led_speed(); + } else { + sony_dgpu_off(); + sony_led_stamina(); + } + return 0; +} static atomic_t sony_pf_users = ATOMIC_INIT(0); static struct platform_driver sony_pf_driver = { + .probe = sony_pf_probe, +#ifdef CONFIG_PM + .resume_early = sony_pf_resume, +#endif .driver = { .name = "sony-laptop", .owner = THIS_MODULE,