Jump to content
  • Announcements

    • Allan

      Forum Rules   04/13/2018

      Hello folks! As some things are being fixed, we'll keep you updated. Per hour the Forum Rules don't have a dedicated "Tab", so here is the place that we have our Rules back. New Users Lounge > [READ] - InsanelyMac Forum Rules - The InsanelyMac Staff Team. 
gsly

HP DVx AppleACPIBatteryManager Driver

74 posts in this topic

Recommended Posts

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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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))
           }
       }

Share this post


Link to post
Share on other sites
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 :unsure:

 

 

 

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 :P

Share this post


Link to post
Share on other sites

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;

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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 :P

 

thanks

 

kidA

Share this post


Link to post
Share on other sites

@gsly,

Thank you for your effort. It looks promising.

Btw, any chance to get source code. Thanks

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites
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!

Share this post


Link to post
Share on other sites
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 :)

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites
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 :)

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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 :blink:

Share this post


Link to post
Share on other sites
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. :blink:

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 !

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Recently Browsing   0 members

    No registered users viewing this page.



×