Jump to content

HP DVx AppleACPIBatteryManager Driver


gsly
 Share

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.

Link to comment
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.

Link to comment
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))
           }
       }

Link to comment
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

Link to comment
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;

Link to comment
Share on other sites

  • 2 weeks later...
  • 3 weeks later...

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

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

Link to comment
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.

Link to comment
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!

Link to comment
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 :)

Link to comment
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.

Link to comment
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

Link to comment
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?

Link to comment
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:

Link to comment
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.

Link to comment
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 !

Link to comment
Share on other sites

 Share

×
×
  • Create New...