brightness key handling on lenovo thinkpad edge E325 (and possibly others)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

Running Debian testing (linux 3.2) on my new thinkpad edge e325 I
noticed the brightness Fn keys being a bit overresponsive: every time I
hit one the brightness changes several levels. I think some of this is
my desktop environment misbehaving, but part of it seems to be
thinkpad_acpi, assuming the documentation's explanation
KEY_BRIGHTNESSDOWN/UP should not be sent if the firmware is handling
brightness is still accurate. Here's what seems to be happening:

On module load we reach tpacpi_check_std_acpi_brightness_support, which
calls tpacpi_acpi_handle_locate with VIDEO_HID (aka LNXVIDEO) to find a
video device. tpacpi_acpi_handle_locate calls acpi_get_devices.
acpi_get_devices returns success, but it never actually calls its
callback function (verified by adding logging to that function). This
exposes a slight bug in tpacpi_acpi_handle_locate: it logs "Found ACPI
handle for video", but at that point device_found is null.
tpacpi_check_std_acpi_brightness_support therefore does not call
tpacpi_query_bcl_levels, leaving bcl_levels at its default value of 0.
This means tp_features.bright_acpimode gets set to 0, while I believe it
should be 1 for this laptop, as that would cause the redundant
thinkpad-acpi brightness events to be disabled.
tpacpi_check_std_acpi_brightness_support then returns 0, which causes
tpacpi_detect_brightness_capabilities to log "detected a 8-level
brightness capable ThinkPad" while the laptop actually supports 16
levels of brightness. That part seems to be purely cosmetic, though.

I have attached a patch (against debian's 3.2 kernel, but it looks like
there has been very little churn in the module recently so I hope this
suffices) that might be a starting point for fixing this. It adds a
device_found check to tpacpi_acpi_handle_locate to fix up the misleading
logging if that function never gets its callback called. It switches to
code directly derived from the kernel's drivers/acpi/video_detect.c to
find a VIDEO_HID device. Finally, it tries to call _BCL on all children
of this device. Together these correctly detect my 16-level brightness
capable E325, and stop the unnecessary KEY_BRIGHTNESSDOWN/UP input
events. It seems quite likely I broke something else, though, especially
as I'm not picky in what I call _BCL on (calling it on the VIDEO_HID
device itself just fails, but I'm now calling it on a few things that do
not support it and ignoring those failures).

I have also attached dmidecode output. I would be happy to provide acpi
tables if you can tell me how to generate useful ones
(Documentation/laptops/thinkpad-acpi.txt does not go into detail on
this).

Further hints on where to go with this, or patches to test, would be
appreciated.


-- 
Marien Zwart
--- linux-2.6-3.2.12/drivers/platform/x86/thinkpad_acpi.c	2012-03-19 17:03:17.000000000 +0100
+++ thinkpad_acpi.c	2012-04-01 22:50:06.704198124 +0200
@@ -87,6 +87,7 @@
 #include <acpi/acpi_drivers.h>
 
 #include <linux/pci_ids.h>
+#include <linux/pci.h>
 
 
 /* ThinkPad CMOS commands */
@@ -724,7 +725,7 @@
 
 	*handle = NULL;
 
-	if (ACPI_SUCCESS(status)) {
+	if (ACPI_SUCCESS(status) && device_found) {
 		*handle = device_found;
 		dbg_printk(TPACPI_DBG_INIT,
 			   "Found ACPI handle for %s\n", name);
@@ -735,6 +736,54 @@
 	}
 }
 
+/* This code is mostly stolen from video_detect.c */
+static acpi_status
+tpacpi_find_video(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+	acpi_handle *result = context;
+	struct pci_dev *dev;
+	struct acpi_device *acpi_dev;
+
+	const struct acpi_device_id video_ids[] = {
+		{ACPI_VIDEO_HID, 0},
+		{"", 0},
+	};
+	if (acpi_bus_get_device(handle, &acpi_dev))
+		return AE_OK;
+
+	if (!acpi_match_device_ids(acpi_dev, video_ids)) {
+		dev = acpi_get_pci_dev(handle);
+		if (!dev)
+			return AE_OK;
+		pci_dev_put(dev);
+
+		*result = acpi_dev->handle;
+	}
+	return AE_OK;
+}
+
+static void __init tpacpi_acpi_locate_video(acpi_handle *handle)
+{
+	acpi_status status;
+
+	BUG_ON(!handle);
+	vdbg_printk(TPACPI_DBG_INIT,
+                    "trying to locate ACPI handle for video\n");
+
+	*handle = NULL;
+	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+                                     ACPI_UINT32_MAX, tpacpi_find_video, NULL,
+                                     handle, NULL);
+
+	if (ACPI_SUCCESS(status) && *handle) {
+		dbg_printk(TPACPI_DBG_INIT, "Found ACPI video handle %p\n", *handle);
+	} else {
+		vdbg_printk(TPACPI_DBG_INIT,
+			    "Could not locate an ACPI video handle: %s\n",
+			    acpi_format_exception(status));
+	}
+}
+
 static void dispatch_acpi_notify(acpi_handle handle, u32 event, void *data)
 {
 	struct ibm_struct *ibm = data;
@@ -6114,23 +6163,37 @@
 static int __init tpacpi_query_bcl_levels(acpi_handle handle)
 {
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	struct acpi_device *acpi_dev, *child_dev;
 	union acpi_object *obj;
-	int rc;
+	int rc = 0, status;
+
+	if (acpi_bus_get_device(handle, &acpi_dev)) {
+		pr_err("acpi_bus_get_device failed\n");
+		return 0;
+	}
+
+
+	list_for_each_entry(child_dev, &acpi_dev->children, node) {
 
-	if (ACPI_SUCCESS(acpi_evaluate_object(handle, "_BCL", NULL, &buffer))) {
-		obj = (union acpi_object *)buffer.pointer;
-		if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
-			pr_err("Unknown _BCL data, please report this to %s\n",
-			       TPACPI_MAIL);
-			rc = 0;
+		status = acpi_evaluate_object(child_dev->handle, "_BCL",
+					      NULL, &buffer);
+
+		if (ACPI_SUCCESS(status)) {
+			obj = (union acpi_object *)buffer.pointer;
+			if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
+				pr_err("Unknown _BCL data, please report this to %s\n",
+				       TPACPI_MAIL);
+			} else {
+				rc = obj->package.count;
+			}
+			kfree(buffer.pointer);
 		} else {
-			rc = obj->package.count;
+			pr_info("_BCL call failed with %s\n",
+			       acpi_format_exception(status));
 		}
-	} else {
-		return 0;
+
 	}
 
-	kfree(buffer.pointer);
 	return rc;
 }
 
@@ -6143,7 +6206,7 @@
 	acpi_handle video_device;
 	int bcl_levels = 0;
 
-	tpacpi_acpi_handle_locate("video", ACPI_VIDEO_HID, &video_device);
+	tpacpi_acpi_locate_video(&video_device);
 	if (video_device)
 		bcl_levels = tpacpi_query_bcl_levels(video_device);
 
# dmidecode 2.11
SMBIOS 2.6 present.
58 structures occupying 1829 bytes.
Table at 0x000F9D00.

Handle 0x0000, DMI type 0, 24 bytes
BIOS Information
	Vendor: LENOVO
	Version: 8SET33WW (1.15 )
	Release Date: 11/17/2011
	Address: 0xE0000
	Runtime Size: 128 kB
	ROM Size: 2048 kB
	Characteristics:
		PCI is supported
		PNP is supported
		BIOS is upgradeable
		BIOS shadowing is allowed
		Boot from CD is supported
		Selectable boot is supported
		EDD is supported
		3.5"/720 kB floppy services are supported (int 13h)
		Print screen service is supported (int 5h)
		8042 keyboard services are supported (int 9h)
		Serial services are supported (int 14h)
		Printer services are supported (int 17h)
		CGA/mono video services are supported (int 10h)
		ACPI is supported
		USB legacy is supported
		BIOS boot specification is supported
		Targeted content distribution is supported
	BIOS Revision: 1.15
	Firmware Revision: 1.17

Handle 0x0001, DMI type 1, 27 bytes
System Information
	Manufacturer: LENOVO
	Product Name: 12973MG
	Version: ThinkPad Edge E325
	Serial Number: <snipped>
	UUID: <snipped>
	Wake-up Type: Power Switch
	SKU Number: Not Specified
	Family: ThinkPad Edge E325

Handle 0x0002, DMI type 2, 15 bytes
Base Board Information
	Manufacturer: LENOVO
	Product Name: 12973MG
	Version: Not Available
	Serial Number: <snipped>
	Asset Tag: Not Available
	Features:
		Board is a hosting board
		Board is replaceable
	Location In Chassis: Not Available
	Chassis Handle: 0x0000
	Type: Unknown
	Contained Object Handles: 0

Handle 0x0003, DMI type 3, 21 bytes
Chassis Information
	Manufacturer: LENOVO
	Type: Notebook
	Lock: Not Present
	Version: Not Available
	Serial Number: <snipped>
	Asset Tag: No Asset Information
	Boot-up State: Unknown
	Power Supply State: Unknown
	Thermal State: Unknown
	Security Status: Unknown
	OEM Information: 0x00000000
	Height: Unspecified
	Number Of Power Cords: Unspecified
	Contained Elements: 0

Handle 0x0004, DMI type 8, 9 bytes
Port Connector Information
	Internal Reference Designator: J1902
	Internal Connector Type: None
	External Reference Designator: Keyboard
	External Connector Type: PS/2
	Port Type: Keyboard Port

Handle 0x0005, DMI type 8, 9 bytes
Port Connector Information
	Internal Reference Designator: J1900
	Internal Connector Type: None
	External Reference Designator: Touch Pad
	External Connector Type: PS/2
	Port Type: Mouse Port

Handle 0x0006, DMI type 8, 9 bytes
Port Connector Information
	Internal Reference Designator: J1300
	Internal Connector Type: None
	External Reference Designator: External LAN
	External Connector Type: RJ-45
	Port Type: Network Port

Handle 0x0007, DMI type 8, 9 bytes
Port Connector Information
	Internal Reference Designator: J1400
	Internal Connector Type: None
	External Reference Designator: Internal LAN
	External Connector Type: RJ-45
	Port Type: Network Port

Handle 0x0008, DMI type 8, 9 bytes
Port Connector Information
	Internal Reference Designator: J1500
	Internal Connector Type: None
	External Reference Designator: USB 0
	External Connector Type: Access Bus (USB)
	Port Type: USB

Handle 0x0009, DMI type 8, 9 bytes
Port Connector Information
	Internal Reference Designator: J1300A
	Internal Connector Type: None
	External Reference Designator: USB 1
	External Connector Type: Access Bus (USB)
	Port Type: USB

Handle 0x000A, DMI type 8, 9 bytes
Port Connector Information
	Internal Reference Designator: J1500
	Internal Connector Type: None
	External Reference Designator: USB 2
	External Connector Type: Access Bus (USB)
	Port Type: USB

Handle 0x000B, DMI type 8, 9 bytes
Port Connector Information
	Internal Reference Designator: J1600
	Internal Connector Type: None
	External Reference Designator: USB 3.0
	External Connector Type: Access Bus (USB)
	Port Type: USB

Handle 0x000C, DMI type 8, 9 bytes
Port Connector Information
	Internal Reference Designator: USB 4
	Internal Connector Type: None
	External Reference Designator: USB 4
	External Connector Type: Access Bus (USB)
	Port Type: USB

Handle 0x000D, DMI type 8, 9 bytes
Port Connector Information
	Internal Reference Designator: USB 5
	Internal Connector Type: None
	External Reference Designator: USB 5
	External Connector Type: Access Bus (USB)
	Port Type: USB

Handle 0x000E, DMI type 8, 9 bytes
Port Connector Information
	Internal Reference Designator: USB 6
	Internal Connector Type: None
	External Reference Designator: USB 6
	External Connector Type: Access Bus (USB)
	Port Type: USB

Handle 0x000F, DMI type 8, 9 bytes
Port Connector Information
	Internal Reference Designator: USB 7
	Internal Connector Type: None
	External Reference Designator: USB 7
	External Connector Type: Access Bus (USB)
	Port Type: USB

Handle 0x0010, DMI type 8, 9 bytes
Port Connector Information
	Internal Reference Designator: J1501
	Internal Connector Type: None
	External Reference Designator: USB 8
	External Connector Type: Access Bus (USB)
	Port Type: USB

Handle 0x0011, DMI type 8, 9 bytes
Port Connector Information
	Internal Reference Designator: J1501
	Internal Connector Type: None
	External Reference Designator: USB 9
	External Connector Type: Access Bus (USB)
	Port Type: USB

Handle 0x0012, DMI type 8, 9 bytes
Port Connector Information
	Internal Reference Designator: J1703
	Internal Connector Type: None
	External Reference Designator: SATA 0 (HDD)
	External Connector Type: SAS/SATA Plug Receptacle
	Port Type: SATA

Handle 0x0013, DMI type 8, 9 bytes
Port Connector Information
	Internal Reference Designator: J1705
	Internal Connector Type: None
	External Reference Designator: SATA 1 (Cable SATA ODD)
	External Connector Type: SAS/SATA Plug Receptacle
	Port Type: SATA

Handle 0x0014, DMI type 8, 9 bytes
Port Connector Information
	Internal Reference Designator: J1501
	Internal Connector Type: None
	External Reference Designator: SATA 2 (eSATA)
	External Connector Type: SAS/SATA Plug Receptacle
	Port Type: SATA

Handle 0x0015, DMI type 8, 9 bytes
Port Connector Information
	Internal Reference Designator: J1702
	Internal Connector Type: None
	External Reference Designator: SATA 3 (e-SATA)
	External Connector Type: SAS/SATA Plug Receptacle
	Port Type: SATA

Handle 0x0016, DMI type 8, 9 bytes
Port Connector Information
	Internal Reference Designator: J2106
	Internal Connector Type: None
	External Reference Designator: Audio Line In
	External Connector Type: Mini Jack (headphones)
	Port Type: Audio Port

Handle 0x0017, DMI type 8, 9 bytes
Port Connector Information
	Internal Reference Designator: J2105
	Internal Connector Type: None
	External Reference Designator: Audio Line Out
	External Connector Type: Mini Jack (headphones)
	Port Type: Audio Port

Handle 0x0018, DMI type 8, 9 bytes
Port Connector Information
	Internal Reference Designator: J3702
	Internal Connector Type: None
	External Reference Designator: SIM Card
	External Connector Type: Other
	Port Type: Other

Handle 0x0019, DMI type 8, 9 bytes
Port Connector Information
	Internal Reference Designator: J3304
	Internal Connector Type: None
	External Reference Designator: SD Card
	External Connector Type: Other
	Port Type: Other

Handle 0x001A, DMI type 8, 9 bytes
Port Connector Information
	Internal Reference Designator: J2108
	Internal Connector Type: None
	External Reference Designator: WEBCAM
	External Connector Type: Other
	Port Type: Other

Handle 0x001B, DMI type 8, 9 bytes
Port Connector Information
	Internal Reference Designator: J900
	Internal Connector Type: None
	External Reference Designator: VGA
	External Connector Type: DB-15 female
	Port Type: Video Port

Handle 0x001C, DMI type 8, 9 bytes
Port Connector Information
	Internal Reference Designator: J1800
	Internal Connector Type: None
	External Reference Designator: LVDS
	External Connector Type: Other
	Port Type: Video Port

Handle 0x001D, DMI type 8, 9 bytes
Port Connector Information
	Internal Reference Designator: J1850
	Internal Connector Type: None
	External Reference Designator: Display Port
	External Connector Type: Other
	Port Type: Video Port

Handle 0x001E, DMI type 9, 17 bytes
System Slot Information
	Designation: MINI PCIE 0 (J3700)
	Type: x1 PCI Express x1
	Current Usage: Available
	Length: Short
	ID: 2
	Characteristics:
		3.3 V is provided
		PME signal is supported
		Hot-plug devices are supported
		SMBus signal is supported
	Bus Address: 0000:00:00.0

Handle 0x001F, DMI type 9, 17 bytes
System Slot Information
	Designation: PCI-E GPP (J3600)
	Type: x1 PCI Express x1
	Current Usage: Available
	Length: Long
	ID: 5
	Characteristics:
		3.3 V is provided
		PME signal is supported
		Hot-plug devices are supported
		SMBus signal is supported
	Bus Address: 0000:00:00.0

Handle 0x0020, DMI type 10, 6 bytes
On Board Device Information
	Type: Video
	Status: Enabled
	Description: AMD Ontario GPU

Handle 0x0021, DMI type 10, 6 bytes
On Board Device Information
	Type: Sound
	Status: Enabled
	Description: AZALIA HD Audio

Handle 0x0022, DMI type 10, 6 bytes
On Board Device Information
	Type: Ethernet
	Status: Enabled
	Description: Broadcom NIC BCM5761E

Handle 0x0023, DMI type 10, 6 bytes
On Board Device Information
	Type: Ethernet
	Status: Enabled
	Description: Atheros NIC AR8151

Handle 0x0024, DMI type 10, 6 bytes
On Board Device Information
	Type: SATA Controller
	Status: Enabled
	Description: AMD Hudsion 1

Handle 0x0025, DMI type 10, 6 bytes
On Board Device Information
	Type: Unknown
	Status: Enabled
	Description: Infineon TPM SLB9635

Handle 0x0026, DMI type 10, 6 bytes
On Board Device Information
	Type: Unknown
	Status: Enabled
	Description: NEC USB3.0 D720200F1

Handle 0x0027, DMI type 11, 5 bytes
OEM Strings
	String 1: OEM default string

Handle 0x0028, DMI type 13, 22 bytes
BIOS Language Information
	Language Description Format: Abbreviated
	Installable Languages: 4
		en-US
		fr-FR
		ja-JP
		ko-KR
	Currently Installed Language: en-US

Handle 0x0029, DMI type 32, 11 bytes
System Boot Information
	Status: No errors detected

Handle 0x002A, DMI type 135, 10 bytes
OEM-specific Type
	Header and Data:
		87 0A 2A 00 54 50 07 03 01 07

Handle 0x002B, DMI type 131, 22 bytes
OEM-specific Type
	Header and Data:
		83 16 2B 00 01 00 00 00 00 00 00 00 00 00 00 00
		00 00 00 00 00 01
	Strings:
		TVT-Enablement

Handle 0x002C, DMI type 135, 34 bytes
OEM-specific Type
	Header and Data:
		87 22 2C 00 54 50 07 04 01 06 01 01 02 00 02 01
		02 00 03 01 02 00 04 01 02 00 05 01 02 00 06 01
		02 00

Handle 0x002D, DMI type 200, 7 bytes
OEM-specific Type
	Header and Data:
		C8 07 2D 00 01 02 03
	Strings:
		152D
		PS3A
		BQ3C61

Handle 0x002E, DMI type 4, 42 bytes
Processor Information
	Socket Designation: Socket FT1
	Type: Central Processor
	Family: <OUT OF SPEC>
	Manufacturer: AMD
	ID: 20 0F 50 00 FF FB 8B 17
	Version: AMD E-450 APU with Radeon(tm) HD Graphics
	Voltage: 1.4 V
	External Clock: 100 MHz
	Max Speed: 1650 MHz
	Current Speed: 1650 MHz
	Status: Populated, Enabled
	Upgrade: None
	L1 Cache Handle: 0x002F
	L2 Cache Handle: 0x0030
	L3 Cache Handle: Not Provided
	Serial Number: Not Specified
	Asset Tag: Not Specified
	Part Number: Not Specified
	Core Count: 2
	Core Enabled: 2
	Thread Count: 2
	Characteristics:
		64-bit capable

Handle 0x002F, DMI type 7, 19 bytes
Cache Information
	Socket Designation: L1 Cache
	Configuration: Enabled, Not Socketed, Level 1
	Operational Mode: Write Back
	Location: Internal
	Installed Size: 128 kB
	Maximum Size: 128 kB
	Supported SRAM Types:
		Pipeline Burst
	Installed SRAM Type: Pipeline Burst
	Speed: 1 ns
	Error Correction Type: Multi-bit ECC
	System Type: Unified
	Associativity: 2-way Set-associative

Handle 0x0030, DMI type 7, 19 bytes
Cache Information
	Socket Designation: L2 Cache
	Configuration: Enabled, Not Socketed, Level 2
	Operational Mode: Write Back
	Location: Internal
	Installed Size: 1024 kB
	Maximum Size: 1024 kB
	Supported SRAM Types:
		Pipeline Burst
	Installed SRAM Type: Pipeline Burst
	Speed: 1 ns
	Error Correction Type: Multi-bit ECC
	System Type: Unified
	Associativity: 16-way Set-associative

Handle 0x0031, DMI type 16, 15 bytes
Physical Memory Array
	Location: System Board Or Motherboard
	Use: System Memory
	Error Correction Type: None
	Maximum Capacity: 32 GB
	Error Information Handle: Not Provided
	Number Of Devices: 1

Handle 0x0032, DMI type 19, 15 bytes
Memory Array Mapped Address
	Starting Address: 0x00000000000
	Ending Address: 0x0007FFFFFFF
	Range Size: 2 GB
	Physical Array Handle: 0x0031
	Partition Width: 2

Handle 0x0033, DMI type 17, 28 bytes
Memory Device
	Array Handle: 0x0031
	Error Information Handle: Not Provided
	Total Width: 64 bits
	Data Width: 64 bits
	Size: 2048 MB
	Form Factor: SODIMM
	Set: 1
	Locator: J400
	Bank Locator: Channel A
	Type: DDR3
	Type Detail: Synchronous
	Speed: 1333 MHz
	Manufacturer: 802C
	Serial Number: 332B6D2C
	Asset Tag: 0918
	Part Number: 384B544632353636
	Rank: Unknown

Handle 0x0034, DMI type 20, 19 bytes
Memory Device Mapped Address
	Starting Address: 0x00000000000
	Ending Address: 0x0007FFFFFFF
	Range Size: 2 GB
	Physical Device Handle: 0x0033
	Memory Array Mapped Address Handle: 0x0032
	Partition Row Position: 2
	Interleave Position: 2
	Interleaved Data Depth: 6

Handle 0x0035, DMI type 135, 36 bytes
OEM-specific Type
	Header and Data:
		87 24 35 00 54 50 07 02 42 41 59 20 49 2F 4F 20
		02 00 02 00 00 00 00 18 31 26 31 FF 00 00 00 18
		31 26 31 00

Handle 0x0036, DMI type 133, 5 bytes
OEM-specific Type
	Header and Data:
		85 05 36 00 01
	Strings:
		KHOIHGIUCCHHII

Handle 0x0037, DMI type 15, 29 bytes
System Event Log
	Area Length: 50 bytes
	Header Start Offset: 0x0000
	Header Length: 16 bytes
	Data Start Offset: 0x0010
	Access Method: General-purpose non-volatile data functions
	Access Address: 0x00F0
	Status: Valid, Not Full
	Change Token: 0x00000002
	Header Format: Type 1
	Supported Log Type Descriptors: 3
	Descriptor 1: POST error
	Data Format 1: POST results bitmap
	Descriptor 2: Single-bit ECC memory error
	Data Format 2: Multiple-event
	Descriptor 3: Multi-bit ECC memory error
	Data Format 3: Multiple-event

Handle 0x0038, DMI type 135, 18 bytes
OEM-specific Type
	Header and Data:
		87 12 38 00 54 50 07 01 01 00 01 00 00 00 01 00
		00 00

Handle 0xFEFF, DMI type 127, 4 bytes
End Of Table

Attachment: signature.asc
Description: This is a digitally signed message part

------------------------------------------------------------------------------
This SF email is sponsosred by:
Try Windows Azure free for 90 days Click Here 
http://p.sf.net/sfu/sfd2d-msazure
_______________________________________________
ibm-acpi-devel mailing list
ibm-acpi-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/ibm-acpi-devel

[Index of Archives]     [Linux ACPI]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Photo]     [Yosemite Photos]     [Yosemite Advice]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]

  Powered by Linux