gsly Posted December 29, 2010 Share Posted December 29, 2010 Please Note! The following driver has been deprecated. Please switch to the newest version at http://www.insanelymac.com/forum/index.php?showtopic=264597 The following implements a battery manager driver for HP DVx laptops. There are two pieces required to make this work, the AppleACPIBatteryManager.kext (driver) and a DSDT edit. The driver is generic and will probably work on other platforms that properly implement the _BST and _BIF methods in their DSDT. As the HP _BST method on DVx isn't (IMHO) implemented correctly, DVx owners will also have to implement the DSDT edit so that the _BST method returns proper values to the driver in order to calculate the time remaining (to charge or discharge) value. This was tested on an HP DV8 but will likely work on any DVx model that implements a similar DSDT method. Also, I have only tested this on a 32-bit kernel, but it should work on a 64-bit kernel as the driver has been compiled to a 10.6 32/64-bit universal (FAT) binary. 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. Step 1: DSDT Edit In your DSDT.dsl, locate the method UPBS that should look like this: Method (UPBS, 0, NotSerialized) { Store (^^PCI0.LPCB.EC0.MBRM, Local5) If (LNot (And (Local5, 0x8000))) { ShiftRight (Local5, 0x05, Local5) ShiftLeft (Local5, 0x05, Local5) If (LNotEqual (Local5, DerefOf (Index (PBST, 0x02)))) { If (LEqual (^^PCI0.LPCB.EC0.BACR, One)) { Store (FABL, Index (PBST, 0x02)) } Else { Store (Local5, Index (PBST, 0x02)) } } } Store (^^PCI0.LPCB.EC0.MBCV, Index (PBST, 0x03)) Store (^^PCI0.LPCB.EC0.MBST, Index (PBST, Zero)) } If your method matches the above, replace it with: Method (UPBS, 0, NotSerialized) { Store (^^PCI0.LPCB.EC0.MBST, Index (PBST, Zero)) ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x0A, RefOf (Local0)) Store (Local0, Index (PBST, One)) ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x0F, RefOf (Local1)) Store (Local1, Index (PBST, 0x02)) ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x09, RefOf (Local2)) Store (Local2, Index (PBST, 0x03)) } Compile it and install as usual. Step 2: Install Driver Install the kext in /Extra/Extensions, set the permissions and rebuild your kext cache. Reboot. Link to comment Share on other sites More sharing options...
NIXin Posted December 29, 2010 Share Posted December 29, 2010 Looks awesome! I'll try that and if it works, I'll implement the patch to my DSDT Auto-Patch for DVx, if you don't mind :-) On another thought, you should have maybe made this topic in The Genius Bar instead of here. Link to comment Share on other sites More sharing options...
Mammoth Posted December 29, 2010 Share Posted December 29, 2010 Awesome NIXin, that would be great. I'm looking to try it right now. I'll report back my results. Mine doesn't look anything like that. Here is mine: Method (_BST, 0, NotSerialized) { If (ECON) { If (^^PCI0.LPCB.EC0.MBTS) { UPBS () } Else { IVBS () } } Else { IVBS () } Return (PBST) } Method (UPBI, 0, NotSerialized) { If (LNot (^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x10, RefOf (Local5)))) { If (LAnd (Local5, LNot (And (Local5, 0x8000)))) { ShiftRight (Local5, 0x05, Local5) ShiftLeft (Local5, 0x05, Local5) Store (Local5, Index (PBIF, 0x02)) Divide (Local5, 0x64, , Local2) Add (Local2, One, Local2) Multiply (Local2, 0x0C, Local4) Add (Local4, 0x02, Index (PBIF, 0x05)) Multiply (Local2, 0x07, Local4) Add (Local4, 0x02, Index (PBIF, 0x06)) Multiply (Local2, 0x09, Local4) Add (Local4, 0x02, FABL) } } If (^^PCI0.LPCB.EC0.MBNH) { Store (^^PCI0.LPCB.EC0.BCLB, Local0) Store (^^PCI0.LPCB.EC0.BCHB, Local1) ShiftLeft (Local1, 0x08, Local1) Or (Local0, Local1, Local0) Store (Local0, Index (PBIF, One)) Store (^^PCI0.LPCB.EC0.BVLB, Local0) Store (^^PCI0.LPCB.EC0.BVHB, Local1) ShiftLeft (Local1, 0x08, Local1) Or (Local0, Local1, Local0) Store (Local0, Index (PBIF, 0x04)) Store ("OANI$", Index (PBIF, 0x09)) Store ("NiMH", Index (PBIF, 0x0B)) } Else { Store (^^PCI0.LPCB.EC0.BCLB, Local0) Store (^^PCI0.LPCB.EC0.BCHB, Local1) ShiftLeft (Local1, 0x08, Local1) Or (Local0, Local1, Local0) Store (Local0, Index (PBIF, One)) Store (^^PCI0.LPCB.EC0.BVLB, Local0) Store (^^PCI0.LPCB.EC0.BVHB, Local1) ShiftLeft (Local1, 0x08, Local1) Or (Local0, Local1, Local0) Store (Local0, Index (PBIF, 0x04)) Sleep (0x32) Store ("LION", Index (PBIF, 0x0B)) } Store ("Primary", Index (PBIF, 0x09)) UPUM () Store (One, Index (PBIF, Zero)) } Method (UPUM, 0, NotSerialized) { Store (Buffer (0x0A) { /* 0000 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0008 */ 0x00, 0x00 }, Local0) Store (Buffer (0x05) { 0x36, 0x35, 0x35, 0x33, 0x35 }, Local6) Store (Buffer (0x05) { 0x31, 0x32, 0x33, 0x32, 0x31 }, Local7) Store ("Hewlett-Packard", Index (PBIF, 0x0C)) } Method (UPBS, 0, NotSerialized) { Store (^^PCI0.LPCB.EC0.MBRM, Local5) If (LNot (And (Local5, 0x8000))) { ShiftRight (Local5, 0x05, Local5) ShiftLeft (Local5, 0x05, Local5) If (LNotEqual (Local5, DerefOf (Index (PBST, 0x02)))) { If (LEqual (^^PCI0.LPCB.EC0.BACR, One)) { Store (FABL, Index (PBST, 0x02)) } Else { Store (Local5, Index (PBST, 0x02)) } } } Store (^^PCI0.LPCB.EC0.MBCV, Index (PBST, 0x03)) Store (^^PCI0.LPCB.EC0.MBST, Index (PBST, Zero)) } Method (IVBI, 0, NotSerialized) { Store (0xFFFFFFFF, Index (PBIF, One)) Store (0xFFFFFFFF, Index (PBIF, 0x02)) Store (0xFFFFFFFF, Index (PBIF, 0x04)) Store ("Bad", Index (PBIF, 0x09)) Store ("Bad", Index (PBIF, 0x0A)) Store ("Bad", Index (PBIF, 0x0B)) Store ("Bad", Index (PBIF, 0x0C)) } Method (IVBS, 0, NotSerialized) { Store (Zero, Index (PBST, Zero)) Store (0xFFFFFFFF, Index (PBST, One)) Store (0xFFFFFFFF, Index (PBST, 0x02)) Store (0x2710, Index (PBST, 0x03)) } } Link to comment Share on other sites More sharing options...
gsly Posted December 29, 2010 Author Share Posted December 29, 2010 Looks awesome! I'll try that and if it works, I'll implement the patch to my DSDT Auto-Patch for DVx, if you don't mind :-)On another thought, you should have maybe made this topic in The Genius Bar instead of here. Sure, no problem. Actually, I should have put it under the "Other" subsection of Hardware and Drivers forum. Ah well, this is what the moderators should be doing Mine doesn't look anything like that. Here is mine: Method (_BST, 0, NotSerialized) { If (ECON) { If (^^PCI0.LPCB.EC0.MBTS) { UPBS () } Else { IVBS () } } Else { IVBS () } Return (PBST) } Method (UPBI, 0, NotSerialized) { If (LNot (^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x10, RefOf (Local5)))) { If (LAnd (Local5, LNot (And (Local5, 0x8000)))) { ShiftRight (Local5, 0x05, Local5) ShiftLeft (Local5, 0x05, Local5) Store (Local5, Index (PBIF, 0x02)) Divide (Local5, 0x64, , Local2) Add (Local2, One, Local2) Multiply (Local2, 0x0C, Local4) Add (Local4, 0x02, Index (PBIF, 0x05)) Multiply (Local2, 0x07, Local4) Add (Local4, 0x02, Index (PBIF, 0x06)) Multiply (Local2, 0x09, Local4) Add (Local4, 0x02, FABL) } } If (^^PCI0.LPCB.EC0.MBNH) { Store (^^PCI0.LPCB.EC0.BCLB, Local0) Store (^^PCI0.LPCB.EC0.BCHB, Local1) ShiftLeft (Local1, 0x08, Local1) Or (Local0, Local1, Local0) Store (Local0, Index (PBIF, One)) Store (^^PCI0.LPCB.EC0.BVLB, Local0) Store (^^PCI0.LPCB.EC0.BVHB, Local1) ShiftLeft (Local1, 0x08, Local1) Or (Local0, Local1, Local0) Store (Local0, Index (PBIF, 0x04)) Store ("OANI$", Index (PBIF, 0x09)) Store ("NiMH", Index (PBIF, 0x0B)) } Else { Store (^^PCI0.LPCB.EC0.BCLB, Local0) Store (^^PCI0.LPCB.EC0.BCHB, Local1) ShiftLeft (Local1, 0x08, Local1) Or (Local0, Local1, Local0) Store (Local0, Index (PBIF, One)) Store (^^PCI0.LPCB.EC0.BVLB, Local0) Store (^^PCI0.LPCB.EC0.BVHB, Local1) ShiftLeft (Local1, 0x08, Local1) Or (Local0, Local1, Local0) Store (Local0, Index (PBIF, 0x04)) Sleep (0x32) Store ("LION", Index (PBIF, 0x0B)) } Store ("Primary", Index (PBIF, 0x09)) UPUM () Store (One, Index (PBIF, Zero)) } Method (UPUM, 0, NotSerialized) { Store (Buffer (0x0A) { /* 0000 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0008 */ 0x00, 0x00 }, Local0) Store (Buffer (0x05) { 0x36, 0x35, 0x35, 0x33, 0x35 }, Local6) Store (Buffer (0x05) { 0x31, 0x32, 0x33, 0x32, 0x31 }, Local7) Store ("Hewlett-Packard", Index (PBIF, 0x0C)) } [color="#FF0000"]Method (UPBS, 0, NotSerialized) { Store (^^PCI0.LPCB.EC0.MBRM, Local5) If (LNot (And (Local5, 0x8000))) { ShiftRight (Local5, 0x05, Local5) ShiftLeft (Local5, 0x05, Local5) If (LNotEqual (Local5, DerefOf (Index (PBST, 0x02)))) { If (LEqual (^^PCI0.LPCB.EC0.BACR, One)) { Store (FABL, Index (PBST, 0x02)) } Else { Store (Local5, Index (PBST, 0x02)) } } } Store (^^PCI0.LPCB.EC0.MBCV, Index (PBST, 0x03)) Store (^^PCI0.LPCB.EC0.MBST, Index (PBST, Zero)) } [/color] Method (IVBI, 0, NotSerialized) { Store (0xFFFFFFFF, Index (PBIF, One)) Store (0xFFFFFFFF, Index (PBIF, 0x02)) Store (0xFFFFFFFF, Index (PBIF, 0x04)) Store ("Bad", Index (PBIF, 0x09)) Store ("Bad", Index (PBIF, 0x0A)) Store ("Bad", Index (PBIF, 0x0B)) Store ("Bad", Index (PBIF, 0x0C)) } Method (IVBS, 0, NotSerialized) { Store (Zero, Index (PBST, Zero)) Store (0xFFFFFFFF, Index (PBST, One)) Store (0xFFFFFFFF, Index (PBST, 0x02)) Store (0x2710, Index (PBST, 0x03)) } } You have been working too hard Mammoth! See the part in red above Link to comment Share on other sites More sharing options...
NIXin Posted December 29, 2010 Share Posted December 29, 2010 Here's the fix in Auto-Patcher format (also available in the "DSDT Editor"): # Support for AppleACPIBatteryManager for DVx by gsly: into method label UPBS parent_hid PNP0C0A remove_entry; into device name_hid PNP0C0A insert begin Method (UPBS, 0, NotSerialized)\n {\n Store (^^PCI0.LPCB.EC0.MBST, Index (PBST, Zero))\n ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x0A, RefOf (Local0))\n Store (Local0, Index (PBST, One))\n ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x0F, RefOf (Local1))\n Store (Local1, Index (PBST, 0x02))\n ^^PCI0.LPCB.EC0.SMRD (0x09, 0x16, 0x09, RefOf (Local2))\n Store (Local2, Index (PBST, 0x03))\n } end; Link to comment Share on other sites More sharing options...
Sammity Posted December 30, 2010 Share Posted December 30, 2010 Gsly. Thank you, thank you, thank you ! Correct time now shown on my dv8 for the remaining battery life Awesome. Link to comment Share on other sites More sharing options...
spawnedc Posted January 12, 2011 Share Posted January 12, 2011 Thank you so much for this! You are a lifesaver! Link to comment Share on other sites More sharing options...
kidamnesiac Posted January 28, 2011 Share Posted January 28, 2011 Hi all, I was looking for a voodoo battery kext replacement for my HP DV5 1170el late 2008 hack and found this thread. my dsdt looks like this in the UPBS part Method (UPBS, 0, NotSerialized) { Store (^^PCI0.[color="#ff0000"][b]LPC[/b][/color].EC0.MBRM, Local5) If (LNot (And (Local5, 0x8000))) { ShiftRight (Local5, 0x05, Local5) ShiftLeft (Local5, 0x05, Local5) If (LNotEqual (Local5, DerefOf (Index (PBST, 0x02)))) { Store (Local5, Index (PBST, 0x02)) } } Store (^^PCI0.[b][color="#ff0000"]LPC[/color][/b].EC0.MBCV, Index (PBST, 0x03)) Store (^^PCI0.[b][color="#ff0000"]LPC[/color][/b].EC0.MBST, Index (PBST, Zero)) } slightly different from the one in the first post, obviously the mod didn't compile, because of missing LPCB object ( i have LPC in mine) Any workaround for this? thank you kidA Link to comment Share on other sites More sharing options...
NIXin Posted January 29, 2011 Share Posted January 29, 2011 Did you try changing all the LPBC to LPC and trying the .kext? Link to comment Share on other sites More sharing options...
kidamnesiac Posted January 29, 2011 Share Posted January 29, 2011 I wasn't unsure about that procedure, but I'll try rightaway and give some feedback. kidA Confirmed to work with LPCB -> LPC. thanks! any hint on how to get rid of voodoops2 controller by chance? hehe I wanted to clear the voodoo from my hack thanks kidA Link to comment Share on other sites More sharing options...
valv Posted January 29, 2011 Share Posted January 29, 2011 @gsly, Thank you for your effort. It looks promising. Btw, any chance to get source code. Thanks Link to comment Share on other sites More sharing options...
Pasa Yildirim Posted February 5, 2011 Share Posted February 5, 2011 Have you got the sources? Using similar HP model (8710p), and has the same bug as VoodooBattery: shows "power source: battery" while the battery is disconnected (just on AC). Also, measurement is much slower, and it does not detects properly switching between AC/battery. Link to comment Share on other sites More sharing options...
gsly Posted February 7, 2011 Author Share Posted February 7, 2011 I've been working on an update that includes: ACPI 4.0a compliant _BIX method that returns more data than _BIF Non-standard _BIX method that returns temperature, etc. Info.plist options to enable/disable the above functions. Other fixes to make it behave like AppleSmartBattery (using MacBookPro6,2 as template) I will update the thread in the next few weeks when I'm happy with it. The next task is to try and make this driver obsolete and get the native AppleSmartBattery kext working without OS modification. Link to comment Share on other sites More sharing options...
manmal Posted February 8, 2011 Share Posted February 8, 2011 I've been working on an update that includes: ACPI 4.0a compliant _BIX method that returns more data than _BIF Non-standard _BIX method that returns temperature, etc. Info.plist options to enable/disable the above functions. Other fixes to make it behave like AppleSmartBattery (using MacBookPro6,2 as template) I will update the thread in the next few weeks when I'm happy with it. The next task is to try and make this driver obsolete and get the native AppleSmartBattery kext working without OS modification. WOW! Thanks glsy!! That's GREAT news! Link to comment Share on other sites More sharing options...
MaLd0n Posted February 8, 2011 Share Posted February 8, 2011 great Job Link to comment Share on other sites More sharing options...
Pasa Yildirim Posted February 12, 2011 Share Posted February 12, 2011 I've been working on an update that includes: ACPI 4.0a compliant _BIX method that returns more data than _BIF Non-standard _BIX method that returns temperature, etc. Info.plist options to enable/disable the above functions. Other fixes to make it behave like AppleSmartBattery (using MacBookPro6,2 as template) I will update the thread in the next few weeks when I'm happy with it. The next task is to try and make this driver obsolete and get the native AppleSmartBattery kext working without OS modification. Well, about AppleSmartBattery: it uses SMB device, so you need to add this to your \_SB_.PCI0.EC (\_SB_.C003.C006 for Compaq): Device (SMB0) { Name (_HID, "ACPI0001") Name (_EC, 0x2010) // <-- LOOK HERE Device (SBS0) { Name (_HID, "ACPI0002") Name (_SBS, 0x01) } } If you analyze ACPI spec, you'll see that SMB controller is located within EC at _EC query/offset. Now, my DSDT does not contain SMB, and Windows detects batteries as Control Method, although BIOS supports SmartBattery (and HP also said that all their new models have SMBatteries). Also, yout BAT0 device makes (probably) communication with EC in _BIF/_STA methods. So, we could succeed? Now, problem is ... what is our _EC? I'll try to find it (there is open source implementation in Linux). Second, and worse: according to AppleSmartBattery source, this information is hardcoded: // Register address is 0x29 + SMB base 0x20 ecBehaviorsAddress.addr64 = 0x20 + 0x29; // <-- _EC = 0x2029 ?! So, no vanilla battery ? If you succeed somehow, please share knowledge I wish you good luck Link to comment Share on other sites More sharing options...
NIXin Posted February 12, 2011 Share Posted February 12, 2011 Maybe we can just change the hardcoded address in AppleSmartBattery and recompile it for our purpose? It wouldn't be totally vanilla, but still native functionality. Link to comment Share on other sites More sharing options...
Pasa Yildirim Posted February 12, 2011 Share Posted February 12, 2011 Maybe we can just change the hardcoded address in AppleSmartBattery and recompile it for our purpose? It wouldn't be totally vanilla, but still native functionality. If we get out _EC offset. That's still "the hard part", at least for me Link to comment Share on other sites More sharing options...
gsly Posted February 14, 2011 Author Share Posted February 14, 2011 Maybe we can just change the hardcoded address in AppleSmartBattery and recompile it for our purpose? It wouldn't be totally vanilla, but still native functionality. Been down this road. Apple does not provide the source code that implements an SMBus transaction class that is used by AppleSmartBattery to talk to the EC. I started to build my own class for this, but I'm thinking it might be easier to code on the other side (DSDT) and leave the vanilla driver alone... I can tell you that in an initial experiment, I was able to get the vanilla AppleSmartBattery driver to load and talk to the Smart Battery Subsystem (SBS) and see the information in IOReg with just DSDT code, however it appears the driver stopped polling after a bit. I think I need some logic on the DSDT side to intercept some of the non-standard SBS calls that AppleSmartBattery makes and fake that return information and keeps the kext happy and polling. Link to comment Share on other sites More sharing options...
sw170 Posted February 16, 2011 Share Posted February 16, 2011 Hi 'gsly' AppleACPIBatteryManager with your DSDT mod works great on my system, thanks for that mate, have just one issue and wonder if you could help - after unplugging AC adapter I have about 10-15sec delay from system to switch to battery icon and dim the display, when plugging back AC adapter icon change and display lit up is almost instant. any ideas ? thanks s Link to comment Share on other sites More sharing options...
JBraddock Posted February 16, 2011 Share Posted February 16, 2011 AppleACPIBatteryManager with your DSDT mod works great on my system, thanks for that mate,have just one issue and wonder if you could help - after unplugging AC adapter I have about 10-15sec delay from system to switch to battery icon and dim the display, when plugging back AC adapter icon change and display lit up is almost instant. any ideas ? Slightly off topic but may I ask you what kind of hacks did you use to get the display dimming working? Link to comment Share on other sites More sharing options...
Pasa Yildirim Posted February 16, 2011 Share Posted February 16, 2011 Slightly off topic but may I ask you what kind of hacks did you use to get the display dimming working? You need DSDT injection (Nvidia). Just use GraphicsEnabler and inject missing values, like display-cfg, EDID and powermgmt Then you'll get brightness control and dimming as a gratis Link to comment Share on other sites More sharing options...
JBraddock Posted February 16, 2011 Share Posted February 16, 2011 You need DSDT injection (Nvidia). Just use GraphicsEnabler and inject missing values, like display-cfg, EDID and powermgmt Then you'll get brightness control and dimming as a gratis Thans for the reply. I sent you a PM in order not to invade this thread. Link to comment Share on other sites More sharing options...
gsly Posted February 16, 2011 Author Share Posted February 16, 2011 Hi 'gsly' AppleACPIBatteryManager with your DSDT mod works great on my system, thanks for that mate, have just one issue and wonder if you could help - after unplugging AC adapter I have about 10-15sec delay from system to switch to battery icon and dim the display, when plugging back AC adapter icon change and display lit up is almost instant. any ideas ? thanks s The driver polls/samples the battery status at a regular interval. It defaults to 30 seconds and 1 second when the battery is low. You can see this if you install the debug version and watch the kernel.log with "tail -f" or Console app. You can override the polling internal by setting the key "BatteryPollingPeriodOverride" in the info.plist to the number of seconds you want the driver to check the battery. Link to comment Share on other sites More sharing options...
sw170 Posted February 17, 2011 Share Posted February 17, 2011 The driver polls/samples the battery status at a regular interval. It defaults to 30 seconds and 1 second when the battery is low. You can see this if you install the debug version and watch the kernel.log with "tail -f" or Console app. You can override the polling internal by setting the key "BatteryPollingPeriodOverride" in the info.plist to the number of seconds you want the driver to check the battery. that made the trick, thanks a million gsly ! Link to comment Share on other sites More sharing options...
Recommended Posts