Shutting Down and Power Button Behavior
In order for the phone to behave in a predictable manner when turning off like other smartphones, we need to power off the device in a proper manner/sequence.
The BQ25895 charge controller is able to enter a state known as "ship mode" where the battery is not powering the system at all; the charge controller's SYS output voltage is disabled. This state is entered by setting bit 5 of register 0x09 (BATFET_DIS) in the BQ25895 to 1 (this can be tested by running i2cset -f -y 3 0x6a 0x09 0x64
):
In order to prevent the i.MX 8M from bringing the PMIC's PMIC_ON_REQ pin LOW and having the PMIC turn off the SoC when the power button is being pressed, we need to set the BUTTON_PRESS_TIME bits to being 11:
By doing this, we give ourselves the time we need to properly shut down the device and instead use the charge controller's "ship mode" as the method to completely turn off the device when powered from a battery. If the phone, when powered from just the battery, is instead turned off via the PMIC, then connecting a USB VBUS source would not cause the device to turn on (e.g. presenting some "charging" indication on the screen).
We have tested setting BUTTON_PRESS_TIME to 11 by giving U-Boot the command mw 0x30370038 0x00030020
, this was validated and gave us the expected behavior (pressing and holding the power button didn't cause the PMIC to turn off).
What we want to do instead is establish a time window for how long the user should press the power button in order for the phone to shut down without the use of a dialog. This time window needs to be longer than what will be used to bring up a prompt asking the user if they want to shut down their device, reboot, or whatever else (e.g. 2 seconds for a dialog, handled at a higher level).
The power button is also connected to the QON# pin of the BQ25895 charge controller. When the button is pressed anywhere from 10-18 seconds the charge controller will hard reset the whole board by disabling its SYS output voltage for roughly 500ms. Unfortunately, the BQ25895 has some conflicting documentation when it comes to how long the QON# pin needs to be held LOW for this reset condition to occur, in one instance in the datasheet it says 10 seconds and in the Timing Requirements section they say anywhere from 12 to 18 seconds:
After some brief testing we did, we found that pressing the button for roughly 11 seconds caused the charge controller to reset.
This QON# function of the charge controller is desirable in case the user needs to forcefully hard reset the device for whatever reason (without taking the back cover off). This roughly 10 seconds therefore defines an absolute upper limit for how long the button can be pressed before we initiate a software-controlled power-off sequence.
I suggest using a marker of around 6 seconds of the button being pressed for the OS to initiate shutting down. At the very end of the sequence, we would set bit 5 of register 0x09 in the charge controller to 1, this will completely turn off the device if it is solely powered from a battery. Once the user plugs in a USB VBUS source the charge controller will automatically turn on again and allow the battery to resume powering the system. When in "ship mode" the power button can also be pressed for 1 to 2.25 seconds to turn the charge controller back on. This same method of setting BATFET_DIS to 1, when powered from only a battery, at the very end should also be used if the user selects to turn off their device from a software dialog method.
If needed, the BQ25895 charge controller has the optional ability to turn off the power that the battery supplies to the board after a hard set delay of 10 to 15 seconds (timer is not programmable). To achieve this, we would simply need to set the charge controller's bit 3 of register 0x09 (BATFET_DLY) to 1:
However, there is one caveat to this. When we are shutting down the phone while there is a USB VBUS source present we will have to shut down the device in a different manner, meaning we should not use BATFET_DIS when there is a USB VBUS source present. Instead, when a USB VBUS source is present, we would ideally restart the device and enter U-Boot in some charging state. If this cannot be achieved in the short-term then we can instead turn off the PMIC. The reason for this is because the BQ25895 charge controller will not completely turn off with VBUS present, it will turn off completely only when powered from just the battery.
Obviously, with the display on, a button press of roughly 750ms or less should turn the display off; and if the display is already off then pressing and holding the button should cause the display to come on (effectively regardless of how long you press, then a dialog and shutdown sequence can occur after holding it for an extended period, as described).
All of this can and probably should be tested on the dev kits as well. The same behavior can be accomplished on the dev kit.