gsly Posted August 3, 2011 Share Posted August 3, 2011 The following implements an Advanced Configuration and Power Interface (ACPI) based battery manager kernel extension (kext/driver) for laptops. It should work correctly on any laptop that correctly implements the ACPI standard DSDT methods as defined in the Advanced Configuration and Power Interface Specification 4.0a. Reference documents used: Advanced Configuration and Power Interface (ACPI) Specification 4.0a System Management Bus (SMBus) 2.0 Smart Battery System (SBS) 1.1 The driver has both generic and HP specific functionality that is configurable and it will probably work on all platforms that properly implement the _BST, _BIF and/or _BIX methods in their DSDT. Therefore, there are several installation methods available: Generic platforms: ACPI 3.x _BIF method: Configure key "UseExtendedBatteryInformationMethod" to false in Info.plist and install kext. ACPI 4.x _BIX method: Configure key "UseExtendedBatteryInformationMethod" to true in Info.plist and install kext. Ensure your ACPI _BIF, _BIX, _BST methods return data according to the ACPI specification referenced above. HP DVx platforms: As the HP _BST method on DVx isn't (IMHO) implemented correctly, DVx owners will also have to implement DSDT edits so that the _BST method returns proper values to the driver in order to calculate the time remaining (to charge or discharge) value. In addition, I have rewritten the _BIF method, created a new _BIX and BBIX (Bigger or Better _BIX) to correctly talk to the Smart Battery Subsystem (SBS) via the System Management Bus (SMBus) via the Embedded Controller (EC). This allows the reading of information from the battery that the HP methods do not include like cycle count, temperature and date of manufacture. To support ACPI 3.x _BIF method: Configure key "UseExtendedBatteryInformationMethod" to false in Info.plist and install kext, Modify DSDT methods UPBS, UPBI and ITOS. To support ACPI 4.x _BIX method: Configure key "UseExtendedBatteryInformationMethod" to true in Info.plist and install kext, Modify DSDT methods UPBS, UPBI, ITOS and add _BIX, UPBX and IVBX methods. To support non-ACPI BBIX method: Configure key "UseExtraBatteryInformationMethod" to true in Info.plist and install kext, Modify DSDT methods UPBS, UPBI and ITOS and add BBIX, UPBG and IVBG methods. The BBIX method, although non-standard, returns *all* of the battery information available from SBS including temperature and is basically an extension of the _BIX method. This driver polls the battery state by default every 30 seconds. If you wish to override this value to make the system respond to battery events quicker, you can set "BatteryPollingPeriodOverride" in the Info.plist to the number of seconds between polls. This was tested on an HP DV8 but will likely work on any DVx model that implements similar DSDT methods. Also, I have tested this on both 32-bit/64-bit kernels and the driver has been compiled to a 10.6 32/64-bit universal (FAT) binary. It will also work on 10.7 Lion provided your DSDT methods are performing 8-bit I/O access to the SMBus if accessed through the EC, See "Optional Step 2d: Lion Support for DVx" section for details. Step 1: ACPI 3.x/4.x _BST DSDT edit (Common to all optional steps below): In your DSDT.dsl, locate the BAT0 device and add/replace the following: // Battery status storage Name (PBST, Package (0x04) { Zero, // 0x00, Battery state 0xFFFFFFFF, // 0x01, Battery present rate 0xFFFFFFFF, // 0x02, Battery remaining capacity 0x2710 // 0x03, Battery present voltage }) // Get battery status into PBST Method (UPBS, 0, NotSerialized) { Store (^^PCI0.LPCB.EC0.MBST, Index (PBST, 0x00)) // 0x00, Battery state ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x0a, RefOf (Local0)) // Current() Store (Local0, Index (PBST, 0x01)) // 0x01, Battery present rate ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x0f, RefOf (Local1)) // RemainingCapacity() Store (Local1, Index (PBST, 0x02)) // 0x02, Battery remaining capacity ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x09, RefOf (Local2)) // Voltage() Store (Local2, Index (PBST, 0x03)) // 0x03, Battery present voltage } // InValid Battery Status // Store placeholder battery status in PBST when no battery installed Method (IVBS, 0, NotSerialized) { Store (Zero, Index (PBST, Zero)) // 0x00, Battery state Store (0xFFFFFFFF, Index (PBST, One)) // 0x01, Battery present rate Store (0xFFFFFFFF, Index (PBST, 0x02)) // 0x02, Battery remaining capacity Store (0x2710, Index (PBST, 0x03)) // 0x03, Battery present voltage (10000) } There is a bug in the HP ITOS() Method used by the optional methods below so locate ITOS() under the Scope(_SB) namespace and replace it with: // Function: Integer to ASCII/OS String // // Arg0 = Integer (DWord) to convert // Return = Buffer of ASCII representation (Length = 0x5) Method (ITOS, 1, NotSerialized) { // Buffer to store converted string Store (Buffer (0x06) { 0x20, 0x20, 0x20, 0x20, 0x20, 0x00 }, Local0) // Lookup table for ASCII digit Store (Buffer (0x11) { "0123456789ABCDEF" }, Local7) Store (0x05, Local1) // Counter Store (Zero, Local2) // Index into Local0 (String) While (Local1) { Decrement (Local1) And (ShiftRight (Arg0, ShiftLeft (Local1, 0x02)), 0x0F, Local4) // Get next digit to convert GBFE (Local7, Local4, RefOf (Local5)) // Get ACSII version from Local7 lookup table PBFE (Local0, Local2, Local5) // Put digit in string buffer Increment (Local2) // Index++ } Store(Zero, Index(Local0, Local2)) // Ensure string ends with '\0' Return (Local0) } Optional Step 2a: ACPI 3.x _BIF with SBS information DSDT edit In your DSDT.dsl, locate the BAT0 device and add/replace the following: // Battery information storage Name (PBIF, Package (0x0D) { 0x00000001, // 0x00, Power Unit 0xFFFFFFFF, // 0x01, Design Capacity 0xFFFFFFFF, // 0x02, Last Full Charge Capacity 0x00000001, // 0x03, Battery technology 0xFFFFFFFF, // 0x04, Design voltage 0x000000FA, // 0x05, Design capacity of warning 0x00000096, // 0x06, Design capacity of low 0x0000000A, // 0x07, Battery capacity gradularity 1 0x00000019, // 0x08, Battery capacity gradularity 2 " ", // 0x09, Model number " ", // 0x0a, Serial number " ", // 0x0b, Battery type " " // 0x0c, OEM Information }) // Get and store battery information in PBIF Method (UPBI, 0, NotSerialized) { Store (0x01, Index (PBIF, 0x00)) // 0x00, Power Unit ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x18, RefOf (Local0)) // DesignCapacity() - WORD - unsigned int Store (Local0, Index (PBIF, 0x01)) // 0x01, Design Capacity ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x10, RefOf (Local1)) // FullChargeCapacity() - WORD - unsigned int Store (Local1, Index (PBIF, 0x02)) // 0x02, Last Full Charge Capacity Store (0x01, Index (PBIF, 0x03)) // 0x03, Battery technology ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x19, RefOf (Local2)) // DesignVoltage() - WORD - unsigned int Store (Local2, Index (PBIF, 0x04)) // 0x04, Design voltage Store (0xFA, Index (PBIF, 0x05)) // 0x05, Design capacity of warning Store (0x96, Index (PBIF, 0x06)) // 0x06, Design capacity of low Store (0x0A, Index (PBIF, 0x07)) // 0x07, Battery capacity gradularity 1 Store (0x19, Index (PBIF, 0x08)) // 0x08, Battery capacity gradularity 2 ^^PCI0.LPCB.EC0.SMRD (0x0B, 0x16, 0x21, RefOf (Local3)) // DeviceName() - BLOCK - string Store (Local3, Index (PBIF, 0x09)) // 0x09, Model number ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x1c, RefOf (Local4)) // SerialNumber() - WORD - unsigned int Store (ITOS (ToBCD (Local4)), Index (PBIF, 0x0a)) // 0x0a, Serial number ^^PCI0.LPCB.EC0.SMRD (0x0B, 0x16, 0x22, RefOf (Local5)) // DeviceChemistry() - BLOCK - string Store (Local5, Index (PBIF, 0x0b)) // 0x0b, Battery type ^^PCI0.LPCB.EC0.SMRD (0x0B, 0x16, 0x20, RefOf (Local6)) // ManufacturerName() - BLOCK - string Store (Local6, Index (PBIF, 0x0c)) // 0x0c, OEM Information } // InValid Battery Information // Store placeholder battery information in PBIF when no battery installed Method (IVBI, 0, NotSerialized) { Store (0x00000001, Index (PBIF, Zero)) // 0x00, Power Unit Store (0xFFFFFFFF, Index (PBIF, One)) // 0x01, Design Capacity Store (0xFFFFFFFF, Index (PBIF, 0x02)) // 0x02, Last Full Charge Capacity Store (0x00000001, Index (PBIF, 0x03)) // 0x03, Battery technology Store (0xFFFFFFFF, Index (PBIF, 0x04)) // 0x04, Design voltage Store (0x000000FA, Index (PBIF, 0x05)) // 0x05, Design capacity of warning Store (0x00000096, Index (PBIF, 0x06)) // 0x06, Design capacity of low Store (0x0000000A, Index (PBIF, 0x07)) // 0x07, Battery capacity gradularity 1 Store (0x00000019, Index (PBIF, 0x08)) // 0x08, Battery capacity gradularity 2 Store ("Bad", Index (PBIF, 0x09)) // 0x09, Model number Store ("Bad", Index (PBIF, 0x0A)) // 0x0a, Serial number Store ("Bad", Index (PBIF, 0x0B)) // 0x0b, Battery type Store ("Bad", Index (PBIF, 0x0C)) // 0x0c, OEM Information } Optional Step 2b: ACPI 4.x _BIX with SBS information DSDT edit In your DSDT.dsl, locate the BAT0 device and add/replace the following: // Battery information extended (ACPI 4.0) Name (PBIX, Package (0x14) { 0x00000001, // 0x00, Revision //Integer 0x00000001, // 0x01, Power Unit //Integer (DWORD) 0xFFFFFFFF, // 0x02, Design Capacity //Integer (DWORD) 0xFFFFFFFF, // 0x03, Last Full Charge Capacity //Integer (DWORD) 0x00000001, // 0x04, Battery Technology //Integer (DWORD) 0xFFFFFFFF, // 0x05, Design Voltage //Integer (DWORD) 0x000000FA, // 0x06, Design Capacity of Warning //Integer (DWORD) 0x00000096, // 0x07, Design Capacity of Low //Integer (DWORD) 0x00000000, // 0x08, Cycle Count //Integer (DWORD) 0x00100000, // 0x09, Measurement Accuracy //Integer (DWORD) 0xFFFFFFFF, // 0x0a, Max Sampling Time //Integer (DWORD) 0xFFFFFFFF, // 0x0b, Min Sampling Time //Integer (DWORD) 0xFFFFFFFF, // 0x0c, Max Averaging Interval //Integer (DWORD) 0xFFFFFFFF, // 0x0d, Min Averaging Interval //Integer (DWORD) 0x0000000A, // 0x0e, Battery Capacity Granularity 1 //Integer (DWORD) 0x00000019, // 0x0f, Battery Capacity Granularity 2 //Integer (DWORD) " ", // 0x10, Model Number //String (ASCIIZ) " ", // 0x11, Serial Number //String (ASCIIZ) " ", // 0x12, Battery Type //String (ASCIIZ) " " // 0x13, OEM Information //String (ASCIIZ) }) // Return battery extended information in PBIX Method (_BIX, 0, NotSerialized) { If (ECON) { If (^^PCI0.LPCB.EC0.MBTS) { UPBX () // Return battery information } Else { IVBX () // No battery, return placeholder info } } Else { IVBX () // No battery, return placeholder info } Return (PBIX) } // Get and store battery extended information in PBIX Method (UPBX, 0, NotSerialized) { Store (0x00, Index (PBIX, 0x00)) // 0x01, Revision Store (0x01, Index (PBIX, 0x01)) // 0x01, Power Unit ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x18, RefOf (Local0)) // DesignCapacity() - WORD - unsigned int Store (Local0, Index (PBIX, 0x02)) // 0x02, Design Capacity ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x10, RefOf (Local1)) // FullChargeCapacity() - WORD - unsigned int Store (Local1, Index (PBIX, 0x03)) // 0x03, Last Full Charge Capacity Store (0x01, Index (PBIX, 0x04)) // 0x04, Battery technology ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x19, RefOf (Local2)) // DesignVoltage() - WORD - unsigned int Store (Local2, Index (PBIX, 0x05)) // 0x05, Design voltage Store (0xFA, Index (PBIX, 0x06)) // 0x06, Design capacity of warning Store (0x96, Index (PBIX, 0x07)) // 0x07, Design capacity of low ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x17, RefOf (Local0)) // CycleCount() - WORD - unsigned int Store (Local0, Index (PBIX, 0x08)) // 0x08, Cycle Count ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x0c, RefOf (Local0)) // MaxError() - WORD - unsigned int Multiply (Local0, 0x1000, Index (PBIX, 0x09)) // 0x09, Measurement Accuracy Store (0xFFFFFFFF, Index (PBIX, 0x0a)) // 0x0a, Max Sampling Time Store (0xFFFFFFFF, Index (PBIX, 0x0b)) // 0x0b, Min Sampling Time Store (0x0000EA60, Index (PBIX, 0x0c)) // 0x0c, Max Averaging Interval Store (0x0000EA60, Index (PBIX, 0x0d)) // 0x0d, Min Averaging Interval Store (0x0A, Index (PBIX, 0x0e)) // 0x0e, Battery capacity gradularity 1 Store (0x19, Index (PBIX, 0x0f)) // 0x0f, Battery capacity gradularity 2 ^^PCI0.LPCB.EC0.SMRD (0x0B, 0x16, 0x21, RefOf (Local3)) // DeviceName() - BLOCK - string Store (Local3, Index (PBIX, 0x10)) // 0x10, Model number ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x1c, RefOf (Local4)) // SerialNumber() - WORD - unsigned int Store (ITOS (ToBCD (Local4)), Index (PBIX, 0x11)) // 0x11, Serial number ^^PCI0.LPCB.EC0.SMRD (0x0B, 0x16, 0x22, RefOf (Local5)) // DeviceChemistry() - BLOCK - string Store (Local5, Index (PBIX, 0x12)) // 0x12, Battery type ^^PCI0.LPCB.EC0.SMRD (0x0B, 0x16, 0x20, RefOf (Local6)) // ManufacturerName() - BLOCK - string Store (Local6, Index (PBIX, 0x13)) // 0x0c, OEM Information } // InValid Battery eXtended Information // Store placeholder battery status in PBIX when no battery installed Method (IVBX, 0, NotSerialized) { Store (0x00000000, Index (PBIX, 0x00)) // 0x00, Revision Store (0x00000001, Index (PBIX, 0x01)) // 0x01, Power Unit Store (0xFFFFFFFF, Index (PBIX, 0x02)) // 0x02, Design Capacity Store (0xFFFFFFFF, Index (PBIX, 0x03)) // 0x03, Last Full Charge Capacity Store (0x00000001, Index (PBIX, 0x04)) // 0x04, Battery technology Store (0xFFFFFFFF, Index (PBIX, 0x05)) // 0x05, Design voltage Store (0x000000FA, Index (PBIX, 0x06)) // 0x06, Design capacity of warning Store (0x00000096, Index (PBIX, 0x07)) // 0x07, Design capacity of low Store (0x00000000, Index (PBIX, 0x08)) // 0x08, Cycle Count Store (0x00100000, Index (PBIX, 0x09)) // 0x09, Measurement Accuracy Store (0xFFFFFFFF, Index (PBIX, 0x0a)) // 0x0a, Max Sampling Time Store (0xFFFFFFFF, Index (PBIX, 0x0b)) // 0x0b, Min Sampling Time Store (0x0000EA60, Index (PBIX, 0x0c)) // 0x0c, Max Averaging Interval Store (0x0000EA60, Index (PBIX, 0x0d)) // 0x0d, Min Averaging Interval Store (0x0000000A, Index (PBIX, 0x0e)) // 0x0e, Battery capacity gradularity 1 Store (0x00000019, Index (PBIX, 0x0f)) // 0x0f, Battery capacity gradularity 2 Store ("Bad", Index (PBIX, 0x10)) // 0x10, Model number Store ("Bad", Index (PBIX, 0x11)) // 0x11, Serial number Store ("Bad", Index (PBIX, 0x12)) // 0x12, Battery type Store ("Bad", Index (PBIX, 0x13)) // 0x0c, OEM Information } Optional Step 2c: BBIX with all SBS information DSDT edit In your DSDT.dsl, locate the BAT0 device and add/replace the following: // Battery information - Non-standard stuff OSX will use Name (PBIG, Package (0x10) { 0x00000000, // 0x00, ManufacturerAccess() - WORD - ? 0x00000000, // 0x01, BatteryMode() - WORD - unsigned int 0xFFFFFFFF, // 0x02, AtRateTimeToFull() - WORD - unsigned int (min) 0xFFFFFFFF, // 0x03, AtRateTimeToEmpty() - WORD - unsigned int (min) 0x00000000, // 0x04, Temperature() - WORD - unsigned int (0.1K) 0x00000000, // 0x05, Voltage() - WORD - unsigned int (mV) 0x00000000, // 0x06, Current() - WORD - signed int (mA) 0x00000000, // 0x07, AverageCurrent() - WORD - signed int (mA) 0x00000000, // 0x08, RelativeStateOfCharge() - WORD - unsigned int (%) 0x00000000, // 0x09, AbsoluteStateOfCharge() - WORD - unsigned int (%) 0x00000000, // 0x0a, RemaingingCapacity() - WORD - unsigned int (mAh or 10mWh) 0xFFFFFFFF, // 0x0b, RunTimeToEmpty() - WORD - unsigned int (min) 0xFFFFFFFF, // 0x0c, AverageTimeToEmpty() - WORD - unsigned int (min) 0xFFFFFFFF, // 0x0d, AverageTimeToFull() - WORD - unsigned int (min) 0x00000000, // 0x0e, ManufactureDate() - WORD - unsigned int (packed date) " " // 0x0f, ManufacturerData() - BLOCK - Unknown }) // Return battery extra information in PBIG Method (BBIX, 0, NotSerialized) { If (ECON) { If (^^PCI0.LPCB.EC0.MBTS) { UPBG () // Return battery information } Else { IVBG () // No battery, return placeholder info } } Else { IVBG () // No battery, return placeholder info } Return (PBIG) } // Get and store battery extra information in PBIG Method (UPBG, 0, NotSerialized) { ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x00, RefOf (Local0)) // ManufacturerAccess() - WORD - ? Store (Local0, Index (PBIG, 0x00)) ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x03, RefOf (Local0)) // BatteryMode() - WORD - unsigned int Store (Local0, Index (PBIG, 0x01)) ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x05, RefOf (Local0)) // AtRateTimeToFull() - WORD - unsigned int (min) Store (Local0, Index (PBIG, 0x02)) ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x06, RefOf (Local0)) // AtRateTimeToEmpty() - WORD - unsigned int (min) Store (Local0, Index (PBIG, 0x03)) ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x08, RefOf (Local0)) // Temperature() - WORD - unsigned int (0.1K) Store (Local0, Index (PBIG, 0x04)) ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x09, RefOf (Local0)) // Voltage() - WORD - unsigned int (mV) Store (Local0, Index (PBIG, 0x05)) ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x0a, RefOf (Local0)) // Current() - WORD - signed int (mA) Store (Local0, Index (PBIG, 0x06)) ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x0b, RefOf (Local0)) // AverageCurrent() - WORD - signed int (mA) Store (Local0, Index (PBIG, 0x07)) ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x0d, RefOf (Local0)) // RelativeStateOfCharge() - WORD - unsigned int (%) Store (Local0, Index (PBIG, 0x08)) ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x0e, RefOf (Local0)) // AbsoluteStateOfCharge() - WORD - unsigned int (%) Store (Local0, Index (PBIG, 0x09)) ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x0f, RefOf (Local0)) // RemaingingCapacity() - WORD - unsigned int (mAh or 10mWh) Store (Local0, Index (PBIG, 0x0A)) ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x11, RefOf (Local0)) // RunTimeToEmpty() - WORD - unsigned int (min) Store (Local0, Index (PBIG, 0x0B)) ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x12, RefOf (Local0)) // AverageTimeToEmpty() - WORD - unsigned int (min) Store (Local0, Index (PBIG, 0x0C)) ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x13, RefOf (Local0)) // AverageTimeToFull() - WORD - unsigned int (min) Store (Local0, Index (PBIG, 0x0D)) ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x1b, RefOf (Local0)) // ManufactureDate() - WORD - unsigned int (packed date) Store (Local0, Index (PBIG, 0x0E)) ^^PCI0.LPCB.EC0.SMRD (0x0B, 0x16, 0x23, RefOf (Local0)) // ManufacturerData() - BLOCK - Unknown Store (Local0, Index (PBIG, 0x0F)) } // InValid battery extra information // Store placeholder battery extra information in PBIG when no battery is installed Method (IVBG, 0, NotSerialized) { Store (0x00000000, Index (PBIG, 0x00)) // 0x00, ManufacturerAccess() - WORD - ? Store (0x00000000, Index (PBIG, 0x01)) // 0x01, BatteryMode() - WORD - unsigned int Store (0xFFFFFFFF, Index (PBIG, 0x02)) // 0x02, AtRateTimeToFull() - WORD - unsigned int (min) Store (0xFFFFFFFF, Index (PBIG, 0x03)) // 0x03, AtRateTimeToEmpty() - WORD - unsigned int (min) Store (0x00000000, Index (PBIG, 0x04)) // 0x04, Temperature() - WORD - unsigned int (0.1K) Store (0x00000000, Index (PBIG, 0x05)) // 0x05, Voltage() - WORD - unsigned int (mV) Store (0x00000000, Index (PBIG, 0x06)) // 0x06, Current() - WORD - signed int (mA) Store (0x00000000, Index (PBIG, 0x07)) // 0x07, AverageCurrent() - WORD - signed int (mA) Store (0x00000000, Index (PBIG, 0x08)) // 0x08, RelativeStateOfCharge() - WORD - unsigned int (%) Store (0x00000000, Index (PBIG, 0x09)) // 0x09, AbsoluteStateOfCharge() - WORD - unsigned int (%) Store (0x00000000, Index (PBIG, 0x0a)) // 0x0a, RemaingingCapacity() - WORD - unsigned int (mAh or 10mWh) Store (0xFFFFFFFF, Index (PBIG, 0x0b)) // 0x0b, RunTimeToEmpty() - WORD - unsigned int (min) Store (0xFFFFFFFF, Index (PBIG, 0x0c)) // 0x0c, AverageTimeToEmpty() - WORD - unsigned int (min) Store (0xFFFFFFFF, Index (PBIG, 0x0d)) // 0x0d, AverageTimeToFull() - WORD - unsigned int (min) Store (0x00000000, Index (PBIG, 0x0e)) // 0x0e, ManufactureDate() - WORD - unsigned int (packed date) Store (" ", Index (PBIG, 0x0f)) // 0x0f, ManufacturerData() - BLOCK - Unknown } Optional Step 2d: Lion Support for DVx Due to stricter ACPI Machine Language (AML) parsing in the AppleACPIPlatform.kext in 10.7 Lion, it appears that any registers in the EC operation region (address space) must be accessed with 8-bit (byte) references. On my DV8, the SMBus that talks to the SBS is wired into the EC and therefore we must access these registers with 8-bit references even though the SMBus standard does provide for 16-bit (Word) access, etc. The HP DSDT uses two methods under the EC device to read and write the SMBus, SMRD() and SMWR(). I re-wrote the parts of these methods that did Word and Block (string) I/O to do the same thing via bytes so that the AppleACPIPlatform AML parser would not throw an exception. The first thing we need is a new big-old-ugly field definition for accessing the 32 bytes (256 bits) of SMBus data registers. We need to know the offset of these registers, so looking at the Field definition for EmbeddedController operation region we see: // Embedded controller I/O Registers // SMBus mapped at offset 0x00 OperationRegion (ERAM, EmbeddedControl, Zero, 0xFF) Field (ERAM, ByteAcc, Lock, Preserve) { SMPR, 8, // SMBus Protocol Register SMST, 8, // SMBus Status Register SMAD, 8, // SMBus Address Register SMCM, 8, // SMBus Command Register SMD0, 256, // SMBus Data Register[0-31] ( 32 byte buffer) BCNT, 8, // SMBus Block Count Register SMAA, 8, // SMBus Alarm Address Register SAD0, 8, // SMBus Alarm Data Register[0] SAD1, 8, // SMBus Alarm Data Register[1] ... So we can see the SMBus Data Register starts at offset 0x04, so under the EC device add: // Define 8-bit fields for accessing SMBus data registers [0-31] Field (ERAM, ByteAcc, Lock, Preserve) { Offset (0x04), SM00, 8, SM01, 8, SM02, 8, SM03, 8, SM04, 8, SM05, 8, SM06, 8, SM07, 8, SM08, 8, SM09, 8, SM10, 8, SM11, 8, SM12, 8, SM13, 8, SM14, 8, SM15, 8, SM16, 8, SM17, 8, SM18, 8, SM19, 8, SM20, 8, SM21, 8, SM22, 8, SM23, 8, SM24, 8, SM25, 8, SM26, 8, SM27, 8, SM28, 8, SM29, 8, SM30, 8, SM31, 8 } Ya, its ugly, but it works. I'm sure this can be done using an index into the field but I need to research this more. Also under the EC device, replace the SMRD and SMWR methods with these: // SMBus Read // See ACPI Spec, section "12.9 SMBus Host Controller Interface via Embedded Controller" // // Arg0 = Protocol to use // Arg1 = Slave address to read from // Arg2 = Command to send to slave // Arg3 = Return data pointer // // Returns SMBus status (although no caller is checking the status for other than kIOSMBusStatusOK Method (SMRD, 4, NotSerialized) { If (LNot (ECON)) { Return (0x17) // No embedded controller! (kIOSMBusStatusDeviceAccessDenied) } If (LNotEqual (Arg0, 0x07)) // kIOSMBusProtocolReadByte { If (LNotEqual (Arg0, 0x09)) // kIOSMBusProtocolReadWord { If (LNotEqual (Arg0, 0x0B)) // kIOSMBusProtocolReadBlock { Return (0x19) // kIOSMBusStatusHostUnsupportedProtocol } } } Acquire (MUT0, 0xFFFF) // Lock SMBus Store (0x04, Local0) // Try 3 times While (LGreater (Local0, One)) { And (SMST, 0x40, SMST) // Clear status (Don't clear Alarm bit!) Store (Arg2, SMCM) // Command Store (Arg1, SMAD) // Address Store (Arg0, SMPR) // Protocol Store (Zero, Local3) // Timeout counter While (LNot (And (SMST, 0xBF, Local1))) // Is command done? (not Alarm!) { Sleep (0x02) // nope, nap Increment (Local3) // count nap If (LEqual (Local3, 0x32)) // count = 50? { And (SMST, 0x40, SMST) // Send command again! Store (Arg2, SMCM) Store (Arg1, SMAD) Store (Arg0, SMPR) Store (Zero, Local3) // reset counter } } If (LEqual (Local1, 0x80)) // Is command DONE? { Store (Zero, Local0) // Yup, exit retry loop } Else { Decrement (Local0) // Nope, another round please! } } If (Local0) // After 3 attempts, something is FUBAR { Store (And (Local1, 0x1F), Local0) // Return SMBus status error } Else // Command worked, return data { If (LEqual (Arg0, 0x07)) // kIOSMBusProtocolReadByte { Store (SM00, Arg3) // Byte Output } If (LEqual (Arg0, 0x09)) // kIOSMBusProtocolReadWord { Store (SM00, Local4) // Low byte (Word) Store (SM01, Local5) // High byte (Word) ShiftLeft (Local5, 0x08, Local5) // Move high byte into place Or (Local4, Local5, Local6) // Add low byte Store (Local6, Arg3) // Return word } If (LEqual (Arg0, 0x0B)) // kIOSMBusProtocolReadBlock { Store (And (BCNT, 0x1F) , Local3) // Get block count of data (bits0-4 or 01xf) Increment (Local3) // Add one to data count (for '\0') Store (Buffer (Local3) { "" }, Local4) // Create an empty buffer of data count + 1 Decrement (Local3) // Size of data Store (Zero, Local5) // Index into buffer While (LGreater (Local3, Local5)) // More data to copy? { If (LEqual (Local5, 0x00)) { Store (SM00, Local6) } // Get byte of data If (LEqual (Local5, 0x01)) { Store (SM01, Local6) } If (LEqual (Local5, 0x02)) { Store (SM02, Local6) } If (LEqual (Local5, 0x03)) { Store (SM03, Local6) } If (LEqual (Local5, 0x04)) { Store (SM04, Local6) } If (LEqual (Local5, 0x05)) { Store (SM05, Local6) } If (LEqual (Local5, 0x06)) { Store (SM06, Local6) } If (LEqual (Local5, 0x07)) { Store (SM07, Local6) } If (LEqual (Local5, 0x08)) { Store (SM08, Local6) } If (LEqual (Local5, 0x09)) { Store (SM09, Local6) } If (LEqual (Local5, 0x0A)) { Store (SM10, Local6) } If (LEqual (Local5, 0x0B)) { Store (SM11, Local6) } If (LEqual (Local5, 0x0C)) { Store (SM12, Local6) } If (LEqual (Local5, 0x0D)) { Store (SM13, Local6) } If (LEqual (Local5, 0x0E)) { Store (SM14, Local6) } If (LEqual (Local5, 0x0F)) { Store (SM15, Local6) } If (LEqual (Local5, 0x10)) { Store (SM16, Local6) } If (LEqual (Local5, 0x11)) { Store (SM17, Local6) } If (LEqual (Local5, 0x12)) { Store (SM18, Local6) } If (LEqual (Local5, 0x13)) { Store (SM19, Local6) } If (LEqual (Local5, 0x14)) { Store (SM20, Local6) } If (LEqual (Local5, 0x15)) { Store (SM21, Local6) } If (LEqual (Local5, 0x16)) { Store (SM22, Local6) } If (LEqual (Local5, 0x17)) { Store (SM23, Local6) } If (LEqual (Local5, 0x18)) { Store (SM24, Local6) } If (LEqual (Local5, 0x19)) { Store (SM25, Local6) } If (LEqual (Local5, 0x1A)) { Store (SM26, Local6) } If (LEqual (Local5, 0x1B)) { Store (SM27, Local6) } If (LEqual (Local5, 0x1C)) { Store (SM28, Local6) } If (LEqual (Local5, 0x1D)) { Store (SM29, Local6) } If (LEqual (Local5, 0x1E)) { Store (SM30, Local6) } If (LEqual (Local5, 0x1F)) { Store (SM31, Local6) } PBFE (Local4, Local5, Local6) // Store byte in buffer Increment (Local5) // Next! } PBFE (Local4, Local5, Zero) // Finish buffer with '\0' or 0x00 Store (Local4, Arg3) // Return buffer/block } } Release (MUT0) // Release SMBus lock Return (Local0) // Return 0 (OK) } // SMBus Write // See ACPI Spec, section "12.9 SMBus Host Controller Interface via Embedded Controller" // // Arg0 = Protocol to use // Arg1 = Slave address to write to // Arg2 = Command to send to slave // Arg3 = Pointer to data to write Method (SMWR, 4, NotSerialized) { If (LNot (ECON)) { Return (0x17) // No embedded controller! (kIOSMBusStatusDeviceAccessDenied) } If (LNotEqual (Arg0, 0x06)) // kIOSMBusProtocolWriteByte { If (LNotEqual (Arg0, 0x08)) // kIOSMBusProtocolWriteWord { If (LNotEqual (Arg0, 0x0A)) // kIOSMBusProtocolWriteBlock { Return (0x19) // kIOSMBusStatusHostUnsupportedProtocol } } } Acquire (MUT0, 0xFFFF) // Lock SMBus Store (0x04, Local0) // 3 tries While (LGreater (Local0, One)) { If (LEqual (Arg0, 0x06)) { Store (Arg3, SM00) // Byte to write } If (LEqual (Arg0, 0x08)) { Store (Arg3, Local6) // Word to write And (Local6, 0xFF, Local4) // Low byte ShiftRight (Local6, 0x08, Local5) // High byte Store (Local4, SM00) // Low byte (Word) Store (Local5, SM01) // High byte (Word) } If (LEqual (Arg0, 0x0A)) { Store (SizeOf (Arg3), Local3) // Get buffer/block/string size And (Local3, 0x1F, Local3) // Limit to 32 bytes! Store (Arg3, Local4) // Buffer/block/string pointer Store (Zero, Local5) // Index into buffer While (LGreater (Local3, Local5)) // More data to copy? { GBFE (Local4, Local5, RefOf (Local6)) // Get byte from buffer If (LEqual (Local5, 0x00)) { Store (Local6, SM00) } // Write byte of data If (LEqual (Local5, 0x01)) { Store (Local6, SM01) } If (LEqual (Local5, 0x02)) { Store (Local6, SM02) } If (LEqual (Local5, 0x03)) { Store (Local6, SM03) } If (LEqual (Local5, 0x04)) { Store (Local6, SM04) } If (LEqual (Local5, 0x05)) { Store (Local6, SM05) } If (LEqual (Local5, 0x06)) { Store (Local6, SM06) } If (LEqual (Local5, 0x07)) { Store (Local6, SM07) } If (LEqual (Local5, 0x08)) { Store (Local6, SM08) } If (LEqual (Local5, 0x09)) { Store (Local6, SM09) } If (LEqual (Local5, 0x0A)) { Store (Local6, SM10) } If (LEqual (Local5, 0x0B)) { Store (Local6, SM11) } If (LEqual (Local5, 0x0C)) { Store (Local6, SM12) } If (LEqual (Local5, 0x0D)) { Store (Local6, SM13) } If (LEqual (Local5, 0x0E)) { Store (Local6, SM14) } If (LEqual (Local5, 0x0F)) { Store (Local6, SM15) } If (LEqual (Local5, 0x10)) { Store (Local6, SM16) } If (LEqual (Local5, 0x11)) { Store (Local6, SM17) } If (LEqual (Local5, 0x12)) { Store (Local6, SM18) } If (LEqual (Local5, 0x13)) { Store (Local6, SM19) } If (LEqual (Local5, 0x14)) { Store (Local6, SM20) } If (LEqual (Local5, 0x15)) { Store (Local6, SM21) } If (LEqual (Local5, 0x16)) { Store (Local6, SM22) } If (LEqual (Local5, 0x17)) { Store (Local6, SM23) } If (LEqual (Local5, 0x18)) { Store (Local6, SM24) } If (LEqual (Local5, 0x19)) { Store (Local6, SM25) } If (LEqual (Local5, 0x1A)) { Store (Local6, SM26) } If (LEqual (Local5, 0x1B)) { Store (Local6, SM27) } If (LEqual (Local5, 0x1C)) { Store (Local6, SM28) } If (LEqual (Local5, 0x1D)) { Store (Local6, SM29) } If (LEqual (Local5, 0x1E)) { Store (Local6, SM30) } If (LEqual (Local5, 0x1F)) { Store (Local6, SM31) } Increment (Local5) // Next! } Store (And (Local3, 0x1F), BCNT) // Store block count (limit to 32!) } And (SMST, 0x40, SMST) // Don't clear Alarm bit! Store (Arg2, SMCM) // Command Store (Arg1, SMAD) // Address Store (Arg0, SMPR) // Protocol Store (Zero, Local3) // timeout counter While (LNot (And (SMST, 0xBF, Local1))) // Is command done? (not Alarm!) { Sleep (0x02) // nap Increment (Local3) // count If (LEqual (Local3, 0x32)) // count = 50? { And (SMST, 0x40, SMST) // Send command again! Store (Arg2, SMCM) Store (Arg1, SMAD) Store (Arg0, SMPR) Store (Zero, Local3) } } If (LEqual (Local1, 0x80)) // Command DONE? { Store (Zero, Local0) // Yup, exit retry loop } Else { Decrement (Local0) // Another round! } } If (Local0) // If we tried 3 times, FUBAR! { Store (And (Local1, 0x1F), Local0) // Return error } Release (MUT0) // Release SMBus lock Return (Local0) // Return 0 (OK) } Compile the DSDT and install as usual. Step 3: Install Driver Install the kext in /Extra/Extensions, set the permissions and options in Info.plust, rebuild your kext cache. Reboot. There are two zip files below, a debug and release version. The debug version outputs messages to kernel.log and the release version does not, otherwise they are identical. AppleACPIBatteryManager_20110802_release.zip AppleACPIBatteryManager_20110802_debug.zip The following two drivers are identical to the above versions except the driver classes and kext have been renamed to the same as Apple's Smart Battery Manager and therefore allows some 3rd party application such as iStat Menus and coconutBattery to work. AppleSmartBatteryManager_20110802_release.zip AppleSmartBatteryManager_20110802_debug.zip Source code: https://github.com/gsly/OS-X-ACPI-Battery-Driver Change Log 2012-05-08 Added source code link 2011-09-25 Added reference document links Reordered this change log so latest changes are at the top 2011-09-21 Added "Optional Step 2d: Lion Support for DVx" section. 2011-08-05 Renamed drivers classes to allow compatibility with some 3rd party battery information application. Added new driver binaries for 2011.0802 release. 2011-08-04 Updated DSDT code in posting with stock EC0 device name. 2011-08-02 Added ACPI 4.x support. Added non-standard support for temperature. Compiled with XCode 4. Lots of debugging. 4 1 Link to comment Share on other sites More sharing options...
NIXin Posted August 4, 2011 Share Posted August 4, 2011 Heeey! AWESOME Thanks gsly, you're THE man! I will test now and give feedback soon. One question. Will this work on 10.7? Link to comment Share on other sites More sharing options...
buoo Posted August 4, 2011 Share Posted August 4, 2011 A long time has passed since the last time I heard a project like this. I have to say that there are few solutions for the laptop batteries. I'll try it as soon as possible! Thanks ^^ Link to comment Share on other sites More sharing options...
gsly Posted August 4, 2011 Author Share Posted August 4, 2011 Heeey! AWESOME Thanks gsly, you're THE man!I will test now and give feedback soon. One question. Will this work on 10.7? I have not tested it on 10.7 yet. I wanted to get this release out before I get into 10.7 support/changes. I've been able to install 10.7 but I have a bit more work to get it working the same as my 10.6.8 install, but I'll be working on that in the next week or so after which I'll see if the code can be adapted to 10.7 or if I need to switch to Plan B Link to comment Share on other sites More sharing options...
manmal Posted August 4, 2011 Share Posted August 4, 2011 I have not tested it on 10.7 yet. I wanted to get this release out before I get into 10.7 support/changes. I've been able to install 10.7 but I have a bit more work to get it working the same as my 10.6.8 install, but I'll be working on that in the next week or so after which I'll see if the code can be adapted to 10.7 or if I need to switch to Plan B Thank you very very much glsy for this new driver !! A couple questions : 1) Which fixes did you apply for your dv8 (expecially for step2)? 2a+2b+2c or just one of them ? Which is the one you consider the best for dv8? 2a,2b or 2c, in case you have to choose just one of such fixes you posted? 2) Does the new driver provide a "method" to put dv8 on sleep (or hibernate mode) when battery goes under a certain percentage, like in true macs (without powering it on and sleep again when near to zero)? I have a macbookpro and it gives the first advice when it is about 10% and puts it in sleep mode automatically when lower than 5% . If you need something to test on my mbp15 just let me know... Mal PS: Would you share your updated dv8 dsdt.aml, just for "learning" purpose to see what did you apply and so on? Link to comment Share on other sites More sharing options...
Peter_sm Posted August 4, 2011 Share Posted August 4, 2011 Hi, There is a great DSDT for DV8 where sound and brightness/video is updated for LION in this post http://www.insanelymac.com/forum/index.php...t&p=1727179 //Peter Link to comment Share on other sites More sharing options...
NIXin Posted August 4, 2011 Share Posted August 4, 2011 I had to change all the PCI0.LPCB.EC references to PCI0.LPCB.EC0. And unfortunately it does not work on Lion at this state. I will try my backup 10.6 system. EDIT: Works nicely on 10.6, great job! Waiting for the 10.7 update Link to comment Share on other sites More sharing options...
JBraddock Posted August 4, 2011 Share Posted August 4, 2011 Nicely done gsly I can't wait to test this on Lion. Thanks, Link to comment Share on other sites More sharing options...
MacKonsti Posted August 4, 2011 Share Posted August 4, 2011 Guys, it this kext only restricted to HP laptops? What about netbooks? I was thinking of installing it on my Dell Mini 10v but I know for a fact that the battery DSDT section is more messy that the code posted by gsly. Any means of checking out if this works on other laptops, by a Terminal command for example, before tampering with a nicely-working 10.6.7 system? Cheers! Link to comment Share on other sites More sharing options...
gsly Posted August 4, 2011 Author Share Posted August 4, 2011 1) Which fixes did you apply for your dv8 (expecially for step2)? 2a+2b+2c or just one of them ? Which is the one you consider the best for dv8? 2a,2b or 2c, in case you have to choose just one of such fixes you posted? Personally, I use the full 2a+2b+2c for testing full functionality. The methods are independent of one another so you can put them all in your DSDT and use what you want. 2) Does the new driver provide a "method" to put dv8 on sleep (or hibernate mode) when battery goes under a certain percentage, like in true macs (without powering it on and sleep again when near to zero)? I have a macbookpro and it gives the first advice when it is about 10% and puts it in sleep mode automatically when lower than 5% . If you need something to test on my mbp15 just let me know... As mentioned in this http://www.insanelymac.com/forum/index.php...t&p=1657247 posting, the battery driver provided here (and same as the Apple driver) does not put the system to sleep. It simply supplies power information to the power management layer and its that layer that will issue the "system is going to sleep" message. The problem with auto-sleep is that software can "override" the system request to sleep, but I believe the issue on our hackitoshes is that some drivers are not built to properly respond to the sleep request and hence the power management layer never issues the sleep command as not all of the bits of the system acknowledged and shut themselves down. If you google a bit on the subject, you'll find that real Macs suffer from the same issue, although to a lesser degree. Also, it you look at the power management source code for 10.7, you'll see lots of changes in the PM layer and little in the battery driver which suggests to me that Apple is still trying to fix it I had to change all the PCI0.LPCB.EC references to PCI0.LPCB.EC0.And unfortunately it does not work on Lion at this state. I will try my backup 10.6 system. EDIT: Works nicely on 10.6, great job! Waiting for the 10.7 update Whoops! Thanks NIXin, I forgot I had renamed my EC0 device to EC (same as MacBookPro6,1). I updated the OP with the stock EC0 reference. Guys, it this kext only restricted to HP laptops? What about netbooks? I was thinking of installing it on my Dell Mini 10v but I know for a fact that the battery DSDT section is more messy that the code posted by gsly. Follow the Generic Platform instructions. The hardest part of course is to figure out how your system talks to the battery and returns information (SMI/SMM, EC/SMBus, etc) and coding the _BST, _BIF or _BIX methods to return the data in the ACPI defined structure. Link to comment Share on other sites More sharing options...
NIXin Posted August 4, 2011 Share Posted August 4, 2011 How do we read out all the battery information? System profiler shows most of that stuff, but no battery temperature for example. Also, iStat Pro doesn't see the battery at all ("no battery present"). Again, many thanks gsly, for this great contribution! Link to comment Share on other sites More sharing options...
JBraddock Posted August 4, 2011 Share Posted August 4, 2011 How do we read out all the battery information? System profiler shows most of that stuff, but no battery temperature for example.Also, iStat Pro doesn't see the battery at all ("no battery present"). Again, many thanks gsly, for this great contribution! Try this version of iStat. Link to comment Share on other sites More sharing options...
Fraom Posted August 4, 2011 Share Posted August 4, 2011 It work on hp dv6 AMD ?? Link to comment Share on other sites More sharing options...
gsly Posted August 4, 2011 Author Share Posted August 4, 2011 How do we read out all the battery information? System profiler shows most of that stuff, but no battery temperature for example.Also, iStat Pro doesn't see the battery at all ("no battery present"). Again, many thanks gsly, for this great contribution! iStat and several other tools I looked at do not see the battery as they are hard-coded to look at AppleSmartBatteryManager/AppleSmartBatteryDevice in the IORegistery. As this driver is based on the old Apple ACPI legacy code, the class names are different. In theory, I should be able to resolve this by renaming the classes to match Apple's current driver. I may do this if I can figure out how to get Xcode's refactor to work (always greyed out when I tried it before) Link to comment Share on other sites More sharing options...
gsly Posted August 5, 2011 Author Share Posted August 5, 2011 How do we read out all the battery information? System profiler shows most of that stuff, but no battery temperature for example.Also, iStat Pro doesn't see the battery at all ("no battery present"). Again, many thanks gsly, for this great contribution! NIXin/JBraddock, I confirmed my suspicion about just renaming the class files to get some of the 3rd party software to work. XCode's refactoring is {censored} so I had to rename the classes and a LOT of other stuff in the project to enable me to build "AppleSmartBatteryManager" vs. "AppleACPIBatteryManager". After removing the latter and installing the former, I was able to see data in iStat (unhacked) and coconutBattery as you can see: EDIT: Added compiled versions for the renamed driver in original post. Link to comment Share on other sites More sharing options...
NIXin Posted August 6, 2011 Share Posted August 6, 2011 neat! awaiting the 10.7 version then, and it will all be perfect Link to comment Share on other sites More sharing options...
BlackCH Posted August 6, 2011 Share Posted August 6, 2011 EDIT: Added compiled versions for the renamed driver in original post. Hi, thanks for this one! It works good with iStat, like you said. Im trying to use some of your code on my dsdt, but I have a different machine (HP 6720s) because in my opinion the original code is not quite right (wrong readings in OSX and windows). If you could share your DSDT so I can compare the different methods would be great. Also if you like to have a look to the bat0 code from my laptop, here it is: bat.dsl.zip Thanks again! Link to comment Share on other sites More sharing options...
gsly Posted August 6, 2011 Author Share Posted August 6, 2011 Im trying to use some of your code on my dsdt, but I have a different machine (HP 6720s) because in my opinion the original code is not quite right (wrong readings in OSX and windows). If you could share your DSDT so I can compare the different methods would be great. Also if you like to have a look to the bat0 code from my laptop, here it is:bat.dsl.zip Thanks again! My DSDT methods are posted in #1 except for the SMBus access methods and those are standard and specific to my laptop. It looks like your laptop might use SMI/SMM to read the battery information rather than SMBus. I think you might be right about the original code having bugs as I commented what you posted and the C230 method that actually reads the battery status doesn't store the present rate read from the battery, but rather uses it to return a default value? Device (EC) ---------------------------------------------------------------------- // Is battery installed? // // Arg0 = Battery to read? (Always = 0x01) Method (C22A, 1, Serialized) { C229 (One) // Need to see C229 method! Store (C1CD (), Local0) // C1CD() = Read battery present/status? (Local0 = 0x00 = No, 0x01 = Yes) Store (0x0F, Local1) // Default is no battery present (Bit 4 of _STA return) If (And (Local0, Arg0)) // Is battery present? { Store (0x1F, Local1) // Battery is present/available/etc } Return (Local1) // Return battery status } // Read Battery Status // // Arg0 = Battery to read? Method (C230, 1, Serialized) { ShiftLeft (One, Zero, Local7) // WTF? Shifting 0x01 left 0x00 bits = 0x01 so why is this not: Store (One, Local7) ! C229 (One) // Need to see C229 method! If (LEqual (C22A (Local7), 0x0F)) // Is battery present? { Store (Package (0x04) // No, return dummy/default info { Zero, Ones, Ones, Ones }, PBST) Return (0xFFFFFFFD) // Indicate error to caller } Acquire (C225, 0xFFFF) // Acquire exclusive lock If (Arg0) { Store (0xFF, C21C) // Trigger to read/update battery? } Store (C21C, Local0) // Might be return status Release (C225) // Release lock If (LEqual (And (Local0, Local7), Zero)) { Return (Zero) } Acquire (C1C8, 0xFFFF) // Exclusive lock If (ECOK) // If Embedded Controller enabled { Store (Zero, C1DE) // Need to see how this is used! Store (C1E7, Local0) // C1E7 = PBST[0x00], Battery state Store (C1E8, Local3) // C1E8 = PBST[0x01], Battery present rate Store (C1EA, Index (PBST, 0x02)) // C1EA = PBST[0x02], Battery remaining capacity Store (C1EC, Index (PBST, 0x03)) // C1EC = PBST[0x03], Battery present voltage } Release (C1C8) // release lock // Adjust battery state If (LEqual (C007 (), One)) // C007() = Is AC connected? { And (0xFFFFFFFE, Local0, Local0) // Flip Bit 0: Battery is discharging } Else { And (0xFFFFFFFD, Local0, Local0) // Flip Bit 1: Battery is charging } If (And (Local0, One)) // If battery discharging { Acquire (C225, 0xFFFF) // Exclusive access Store (Local7, C222) // What is C222? Indicator of "on-battery"? Release (C225) // } // Write battery state Store (Local0, Index (PBST, Zero)) // PBST[0x00], Battery state // Adjust present rate If (And (Local0, One)) // If battery discharging { If (LOr (LLess (Local3, 0x0190), LGreater (Local3, 0x1964))) // If PresentRate < 400 or PresentRate > 6500 { Store (DerefOf (Index (PBST, One)), Local5) // Get previous PresentRate into Local5 If (LOr (LLess (Local5, 0x0190), LGreater (Local5, 0x1964))) // If PreviousRate < 400 or PreviousRate > 6500 { Store (0x0D7A, Local3) // PresentRate = 3450 } Else { Store (Local5, Local3) // Store PreviousRate in Local3? WTF? // PresentRate read above never stored/used? } } } // Write adjusted rate Store (Local3, Index (PBST, One)) // PBST[0x01], Battery present rate Acquire (C225, 0xFFFF) // Exclusive access And (C21C, Not (Local7), C21C) // C21C = On AC? (opposite of C222) Release (C225) // release Return (Zero) // No error to caller } ----------------------------------------------------------------------- Scope (\_SB) { Name (PBIF, Package (0x0D) { One, // mAh/mA units 0x0A28, // 2600 mAh Ones, // Unknown last Full Charge capacity One, // Battery technology, 0x01 = Secondary/Rechargable 0x2a30, // 10800 mV = 10.8 V Zero, Zero, 0x64, 0x64, "Primary", "100000", "LIon", "Hewlett-Packard" }) Name (PBST, Package (0x04) { Zero, // No status Zero, // No present rate 0xB010, // Remaining capacity = 45072 mAh 0x40F2 // Present voltage = 16626 mV }) Name (C21E, One) // ? Name (C21F, Zero) // ? Name (C23E, 0x0F) // Last battery device status (_STA) Name (C2B1, One) // ? Device (BAT0) { Name (_HID, EisaId ("PNP0C0A")) Name (_UID, One) Name (_PCL, Package (0x01) { _SB }) // Return battery status // // Return Value: // An Integer containing a device status bitmap: // Bit 0 – Set if the device is present. // Bit 1 – Set if the device is enabled and decoding its resources. // Bit 2 – Set if the device should be shown in the UI. // Bit 3 – Set if the device is functioning properly (cleared if device failed its diagnostics). // Bit 4 – Set if the battery is present. // Bits 5–31 – Reserved (must be cleared). Method (_STA, 0, NotSerialized) { Store (^^PCI0.LPCB.EC.C22A (One), Local0) // Get status of battery one into Local0 If (XOr (C23E, Local0)) // Has battery status changed? { Store (Local0, C23E) // Update last battery status Store (Local0, Local1) If (LNotEqual (Local1, 0x1F)) // If battery not present/enabled/etc. { Store (Zero, Local1) } C1B2 (0xEA3A, Zero, Local1, Zero, Zero) // Need to see what this method does } Return (Local0) // Return battery status } // Return battery information Method (_BIF, 0, NotSerialized) { Store (^^PCI0.LPCB.EC.C22C (), Local0) // C22C() = Read battery information into Local0 If (LEqual (Local0, 0xFFFFFFFD)) // If above returns error { Return (Package (0x0D) // Return dummy battery info { Zero, Ones, Ones, One, Ones, Zero, Zero, Zero, Zero, "", "", "", "" }) } Else { Return (PBIF) // Return battery info filled in by C22C() } } // Return battery information Method (_BST, 0, NotSerialized) { Store (C2B1, Local1) // Get switch status If (C2B1) { Store (Zero, C2B1) // Flip the switch (does something else reset C2B1?) } Store (^^PCI0.LPCB.EC.C230 (Local1), Local0) // C230() = Reads battery status into PBST // Above returns a status in Local0 that is never checked! Stupid code monkey... // 0x00 = No error // 0xFFFFFFFD = Error, no battery present Return (PBST) // Return battery status } } Link to comment Share on other sites More sharing options...
g53 Posted August 13, 2011 Share Posted August 13, 2011 Hi gsly; Here is the debug output with your new kext. I run both with true and false set none seems to do the trick. I am also including my dsdt as it is today. On Battery, it show 20:00 to discharge time left but 0% if I change time left to percentage Once again thanks for your help g53 BatDebugPlugedIn.txt.zip BatDebugOnBat.zip DSDTG53SW.aml.zip Link to comment Share on other sites More sharing options...
leanderK Posted August 17, 2011 Share Posted August 17, 2011 I have a strange problem...It works for me with no slider, but after 10-30 minutes I loose connection, Then it shows that no battery is connected. Sometimes after another 10 minuter, but sometimes only seconds It recognizes it again. Any solution?? Link to comment Share on other sites More sharing options...
gsly Posted August 25, 2011 Author Share Posted August 25, 2011 hi gsly bcc9 post dsdt solution for lion.i try to use it but i can not figure out. plz can you check it http://www.insanelymac.com/forum/index.php...p;#entry1737541 I have seen his post and I've been doing some testing related to this as well as looking into the changes in AppleACPIPlatform that cause this. Nothing significant to report yet. Link to comment Share on other sites More sharing options...
sw170 Posted August 25, 2011 Share Posted August 25, 2011 Hi gsly, finally found time to test your kext with all DSDT code you posted on my dv9000 machine, everything works very nicely, thank you very much for all your work and sharing. For some reason coconut battery ver. 2.7 doesn't work for me, ver 2.6.6 works fine, but I'm not really bothered as I'm not using this program anyway. More important for me would be if your kext could have ability to put computer to sleep on low battery: for example on 5% battery level while is on battery power would tell to system (terminal command): osascript -e 'tell application "System Events" to sleep' possible ? Thanks again swavek EDIT: AppleSmartBatteryManager.kext solved coconut 2.7 and iStat battery info issue EDIT2: BatteryMon.app by KWS here does the job for me. Link to comment Share on other sites More sharing options...
THe KiNG Posted August 27, 2011 Share Posted August 27, 2011 Very good job, congrats! I have some ideas how to bypass Lion ACPI EC SMBus stuff, we might need to implement a fake SMB0 device and put there the SMRD method as Apple does with the hope it will not block it... AFAIK I can test only on Lion DP1, dunno how diff is ACPIPlatform b/w DP1 and GM. L.E. Tested and is not/will not work ever on Lion. I even tested latest apple code from mbair and it prints same errors when debug=0xffff, so the code is still there for other OS but not Lion. Only thing they care is to find the SMB0 device with 0x0f status, rest is driver job... It is a very good solution for Snow but that's it, as far I can see Apple will not allow anything on SMBus within ACPI, or they rushed things, or the plan was to break it. So, that return us to the original driver fix, Link to comment Share on other sites More sharing options...
robi62 Posted August 29, 2011 Share Posted August 29, 2011 Hi I tried you next and now it show in system info but although it show time left of batteryon menu it shows 0% left this is system info Battery Information: Model Information: Serial Number: Unknown-Unknown Charge Information: Charge Remaining (mAh): 2960 Fully Charged: No Charging: No Full Charge Capacity (mAh): 0 Health Information: Cycle Count: 0 Condition: Normal Battery Installed: Yes Amperage (mA): -1712 Voltage (mV): 10838 System Power Settings: AC Power: System Sleep Timer (Minutes): 0 Disk Sleep Timer (Minutes): 0 Display Sleep Timer (Minutes): 24 Automatic Restart on Power Loss: Yes Wake on Clamshell Open: Yes Wake on LAN: Yes Display Sleep Uses Dim: Yes PrioritizeNetworkReachabilityOverSleep: 0 RestartAfterKernelPanic: 157680000 Battery Power: System Sleep Timer (Minutes): 10 Disk Sleep Timer (Minutes): 0 Display Sleep Timer (Minutes): 10 Wake on Clamshell Open: Yes Current Power Source: Yes Display Sleep Uses Dim: Yes Reduce Brightness: Yes RestartAfterKernelPanic: 157680000 Hardware Configuration: UPS Installed: No AC Charger Information: Connected: No Charging: No where should Iput the fix in my dsdt???? I tried a few time with your fix and bbc9 ones but I get error all the time At least is an improvement getting info in system profiler An update change kext infoplist to false now showing percentage but lost system info At least coconut and istat show battery info Link to comment Share on other sites More sharing options...
robi62 Posted August 31, 2011 Share Posted August 31, 2011 Gsly here are the files you asked me at Project Osx dsdt.aml.zip kernelog.zip Thanks Link to comment Share on other sites More sharing options...
Recommended Posts